DYL0109
2025-04-16 75f043dfa6660716364e66ee0b3cf99f44255686
Merge remote-tracking branch 'origin/develop1.0' into dyl_dev
已添加127个文件
已重命名1个文件
已删除4个文件
已修改211个文件
71035 ■■■■■ 文件已修改
.gitignore 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/1-登录页.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/2-1-首页-浅色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/2-2-首页-深色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/3-1-能源实时监测-浅色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/3-2-能源实时监测-深色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/4-1-峰平谷时段统计-浅色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/4-2-峰平谷时段统计-深色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/5-1-区域能耗分析-浅色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/5-2-区域能耗分析-深色.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/image-wxm.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/image-yc.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/image-zhuoyue.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/qq.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/指标配置.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/模型配置.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/统计指标.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/计算公式.png 补丁 | 查看 | 原始文档 | blame | 历史
readme/logo-chinese.png 补丁 | 查看 | 原始文档 | blame | 历史
sql/postgre.sql 41721 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/zhitan-ems_20250325182628.nb3 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/branchanalysis/BranchEnergyAnalysisController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/ComprehensiveStatisticsController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/DailyComprehensiveController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/MonthlyComprehensiveController.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/YearComprehensiveController.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/consumptionanalysis/ConsumptionAnalysisController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricLoadController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricThreePhaseController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/energydatastatistics/EnergyDataStatisticsController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/history/HistoryDataTrendController.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/itemizedenergyanalysis/ItemizedEnergyAnalysisController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/DailyKeyEquipmenteController.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/MonthlyKeyEquipmentController.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/YearKeyEquipmentController.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/meter/MeterController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/model/DaqTemplateController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/model/EnergyIndexController.java 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/model/ModelInfoController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/peakvalley/PeakValleyController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/DailyProcessEnergyController.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/MonthlyProcessEnergyController.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/YearProcessEnergyController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/saving/EnergySavingProgramController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/EnergyConsumeDataController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/EnergyDataItemController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/system/SysProfileController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/core/config/SwaggerConfig.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/resources/application-dev.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/resources/application.yml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/constant/CommonConst.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/core/domain/entity/SysDictType.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/enums/IndexType.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/enums/RetrievalModes.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/utils/ChartUtils.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/utils/DateTimeUtil.java 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/utils/PropUtils.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/utils/TypeTime.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-framework/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-generator/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-generator/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-quartz/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-quartz/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/domain/VO/ItemizedEnergyAnalysisItemVO.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/domain/VO/ItemizedEnergyAnalysisVO.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/dto/ItemizedEnergyAnalysisDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/service/IItemizedEnergyAnalysisService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/service/impl/ItemizedEnergyAnalysisServiceImpl.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/AlarmAnalyisisServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/basicdata/mapper/MeterImplementMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/branchanalysis/domain/BranchAnalysisVO.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/branchanalysis/mapper/BranchAnalysisMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/branchanalysis/service/IBranchAnalysisService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/branchanalysis/service/impl/BranchAnalysisServiceImpl.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/carbonemission/service/impl/CarbonEmissionServiceImpl.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/DailyReport.java 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/MonthlyComprehensive.java 415 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/YearComperhensive.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/DailyComprehensiveMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/MonthlyComprehensiveMapper.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/YearComprehensiveMapper.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IDailyComprehensiveService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/ImonthlyComprehensive.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IyearComprehensive.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/DailyComprehensiveServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/MonthlyComprehensiveServiceImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/YearComprehensiveServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/domain/vo/RankingEnergyData.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/service/impl/ConsumptionAnalysisServiceImpl.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/costmanagement/service/impl/DeviationAnalysisServiceServiceImpl.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/IElectricLoadService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/ElectricLoadServiceImpl.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/ElectricThreePhaseServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energydata/mapper/EnergyDataStatisticMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energydata/service/impl/EnergyDataStatisticServiceImpl.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/home/service/HomePageServiceImpl.java 162 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/DailyKeyEquipmentMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/MonthlyKeyEquipmentMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/YearKeyEquipmentMapper.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IDailyKeyEquipmentService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IMonthlyKeyEquipmentService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IYearKeyEquipmentService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/DailyKeyEquipmentServiceImpl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/MonthlyKeyEquipmentServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/YearKeyEquipmentServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/domain/DaqTemplate.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfo.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfor.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/mapper/DaqTemplateMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/mapper/EnergyIndexMapper.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/mapper/ModelNodeMapper.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/IDaqTemplateService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/IEnergyIndexService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/IModelNodeService.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/impl/DaqTemplateServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/impl/EnergyIndexServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/impl/ModelInfoServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/service/impl/ModelNodeServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/peakvalley/domain/ElectricityPriceDate.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/peakvalley/mapper/PeakValleyMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/peakvalley/service/IPeakValleyService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/peakvalley/service/impl/PeakValleyServiceImpl.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/powerDistribution/domain/PowerDistribution.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/domain/DailyProcessEnergy.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/domain/MonthlyProcessEnergy.java 427 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/domain/YearProcessEnergy.java 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/dto/DataItemQueryDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/DailyProcessEnergyMapper.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/MonthlyProcessEnergyMapper.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/YearProcessEnergyMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/IDailyProcessEnergyService.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/IMonthlyProcessEnergyService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/IYearProcessEnergyService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/DailyProcessEnergyServiceImpl.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/MonthlyProcessEnergyServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/YearProcessEnergyServiceImpl.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/productoutput/services/impl/ProductOutputServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/config/RtdbConfig.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/data/RealtimeDatabaseManager.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/data/influxdb/InfluxDBRepository.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/DataItem.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/WritePoint.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/dto/BranchAnalysisDTO.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/dto/DataItemQueryDTO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/RealtimeDatabaseServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/common/DateTimeUtil.java 750 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/FlowChartsDTO.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/CostTrendEnergyTypeItem.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyConsumeTrendDetailItem.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyConsumeVO.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyCostTrendItem.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyCostTrendPage.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyTypeValueContrastedVO.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/QueryCompareRequest.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IEnergyConsumeDataService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/EnergyConsumeDataServiceImpl.java 498 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/system/mapper/SysRoleMenuMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/system/service/impl/SysRoleServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/basicdata/MeterImplementMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/branchanalysis/BranchAnalysisMapper.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/comprehensivestatistics/DailyComprehensiveMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/comprehensivestatistics/MonthlyComprehensiveMapper.xml 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/comprehensivestatistics/YearComprehensiveMapper.xml 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/dailyprocessenergy/DailyProcessEnergyMapper.xml 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/dailyprocessenergy/MonthlyProcessEnergyMapper.xml 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/dailyprocessenergy/YearProcessEnergyMapper.xml 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/energyData/EnergyDataMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/keyequipment/DailyKeyEquipmentMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/keyequipment/MonthlyKeyEquipmentMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/keyequipment/YearKeyEquipmentMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/model/DaqTemplateMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/model/EnergyIndexMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/model/ModelNodeMapper.xml 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/peakvalley/ElectricityDataItemMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/system/SysConfigMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/system/SysRoleMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/system/SysUserMapper.xml 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/.env.development 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/.gitignore 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/package.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/buildingConsumption/api.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/comprehensiveStatistics/comprehensive.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/comprehensiveStatistics/dailyComprehensive/dailyComprehensive.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/comprehensiveStatistics/monthlyComprehensive/monthlyComprehensive.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/comprehensiveStatistics/processEnergyConsumption.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/comprehensiveStatistics/yearComprehensive/yearComprehensive.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/cost/api.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/energyAnalysis/energyAnalysis.js 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/keyEquipment/api.js 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/powerquality/electric-power-factor/api.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/powerquality/electricThreePhase/api.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/powerquality/load-analysis/api.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/process/api.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/realTimeMonitor/historyDataTrend.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/icons/svg/ai.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/icons/svg/bell.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/2.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/3.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/5.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/6.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/7.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/alarm.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-bg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/robot.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/index.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/menu-fix.scss 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/page.scss 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/ruoyi.scss 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/sidebar.scss 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/variables.module.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Avatar/index.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/BaseCard/BaseCard.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/BaseCard/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Breadcrumb/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Echarts/LineChart.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Hamburger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/HeaderSearch/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/LeftTree/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/TagsView/index.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/TopNav/index.vue 369 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/AppMain.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/Navbar.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/Settings/index.vue 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/Sidebar/index.vue 550 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/TagsView/ScrollPane.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/components/TagsView/index.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/layout/index.vue 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/permission.js 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/router/index.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/store/modules/app.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/store/modules/permission.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/store/modules/settings.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/store/modules/tagsView.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/utils/ruoyi.js 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/alarmmanage/alarmrecord/alarmRecord.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/alarmmanage/energyconsumption/energyConsumption.vue 253 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/alarmmanage/measuremen/measuremen.vue 255 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/auxiliaryentry/electricityinput/electricityinput.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/auxiliaryentry/productoutput/productOutput.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/buildingConsumption/branch-build/index.vue 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/buildingConsumption/item-build/index.vue 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/alarmmaintenance/alarmMaintenance.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/gatewayledger/gatewayLedger.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/gatewaystatus/gatewayStatus.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/prealarmmanage/components/collectionpointmanage/CollectionPointManage.vue 121 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/prealarmmanage/components/statisticalindicatorsmanage/StatisticalIndicatorsManage.vue 123 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/businessconfiguration/prealarmmanage/prealarmmanage.vue 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/carbonemission/carbonEmission.vue 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/comps/LineChart.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/dailyComprehensive/index.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/monthlyComprehensive/index.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/yearComprehensive/index.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/costAnalysis/cost-trend-analysis.vue 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/costAnalysis/energy-trend-analysis.vue 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/dataMonitoring/historyDataTrend/index.vue 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/deepanalysis/deepAnalysis.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energy/energy.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyanalysis/comprehensive/comprehensive.vue 400 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyanalysis/department/department.vue 323 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyanalysis/equipment/equipment.vue 351 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyconservation/policyrule/components/EditModal copy.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyconservation/policyrule/policyRule.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyconservation/projectmanage/projectmanage/projectManage.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyefficiency/benchmarkmanage/benchmarkmanage.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/index.vue 500 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/keyEquipment/comps/LineChart.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/keyEquipment/daily/index.vue 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/keyEquipment/monthly/index.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/keyEquipment/year/index.vue 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/measuringinstruments/distributionroom/distributionroom.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/measuringinstruments/maintain/maintain.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/businessmodel/businessModel.vue 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/businessmodel/components/collectIndicators/CollectIndicators.vue 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/businessmodel/components/deviceConfig/DeviceConfig.vue 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/businessmodel/components/statisticalIndicators/StatisticModal.vue 216 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/businessmodel/components/statisticalIndicators/statisticalIndicators.vue 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/calculationformula/calculationFormula.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/collectindicator/collectIndicator.vue 129 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/energytype/energyType.vue 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/energyvarieties/energyVarieties.vue 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/indexwarehouse/components/deviceConfig/DeviceConfig.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/indexwarehouse/components/statisticalIndicatorManagement/statisticalIndicatorManagement.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/indexwarehouse/indexWarehouse.vue 166 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/modelconfiguration/setpeakvalley/setPeakValley.vue 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/monitor/job/index.vue 346 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/monitor/logininfor/index.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/monitor/online/index.vue 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/monitor/operlog/index.vue 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/peakvalley/period/period.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/peakvalley/timeSharing/timeSharing.vue 331 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/policy/knowledgebase/knowledgeBase.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/poweranalysis/pariPassu/index.vue 580 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/poweranalysis/perPassu/index.vue 579 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/powerquality/load/index.vue 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/powerquality/power/index.vue 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/powerquality/threephase/index.vue 509 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/processEnergy/comps/LineChart.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/processEnergy/daily/index.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/processEnergy/monthly/index.vue 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/processEnergy/year/index.vue 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/realtimemonitor/gatewaystatus/index.vue 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/realtimemonitor/realtimemonitor/components/chart-modal.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/realtimemonitor/realtimemonitor/realtimemonitor.vue 152 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/register.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/components/configure.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/config/index.vue 229 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/dept/index.vue 215 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/dict/index.vue 238 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/menu/index.vue 267 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/name/name.vue 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/post/index.vue 227 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/role/index.vue 455 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/index.vue 511 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/profile/index.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/profile/resetPwd.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/profile/userAvatar.vue 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/profile/userInfo.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/tool/gen/index.vue 283 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/vite.config.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -10,6 +10,12 @@
######################################################################
# IDE
.DS_Store
/.DS_Store
zhitan-admin/.DS_Store
zhitan-admin/src/.DS_Store
zhitan-system/.DS_Store
zhitan-system/src/.DS_Store
### STS ###
.apt_generated
@@ -46,4 +52,6 @@
!*/build/*.html
!*/build/*.xml
*/.DS_Store
uploadPath
LICENSE
@@ -1,20 +1,201 @@
The MIT License (MIT)
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/
Copyright (c) 2018 admin
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
   1. Definitions.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.
      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.
      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.
      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.
      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.
      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).
      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.
      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."
      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.
   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.
   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.
   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:
      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and
      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and
      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and
      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.
      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.
   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.
   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.
   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.
   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.
   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.
   END OF TERMS AND CONDITIONS
   APPENDIX: How to apply the Apache License to your work.
      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.
   Copyright [yyyy] [name of copyright owner]
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
README.md
@@ -1,80 +1,115 @@
<div align="center">
    <img src="readme/logo-chinese.png" alt="输入图片说明" height="150" width="150">
</div>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">智碳能源管理系统</h1>
<h4 align="center">基于SpringBoot和若依框架开发</h4>
<p align="center">基于SpringBoot和若依框架开发</p>
<p align="center">能碳平台后台展示&接口已完全开源,代码完备,功能齐全,运行正常</p>
<p align="center"><span style="color: red;">通过本项目,学习者可以掌握能源管理行业的功能和业务,以及技术架构。</span></p>
<p align="center">
    <a href='https://gitee.com/ustcyc/zhitan-ems/stargazers'><img src='https://gitee.com/ustcyc/zhitan-ems/badge/star.svg?theme=dark' alt='star'></img></a>
    <a href='https://gitee.com/ustcyc/zhitan-ems/members'><img src='https://gitee.com/ustcyc/zhitan-ems/badge/fork.svg?theme=dark' alt='fork'></img></a>
    <a href="https://gitee.com/y_project/RuoYi/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
    <a href='https://gitee.com/liulingling1993/zhitan-ems/stargazers'><img src='https://gitee.com/liulingling1993/zhitan-ems/badge/star.svg?theme=dark' alt='star'></img></a>
    <a href='https://gitee.com/liulingling1993/zhitan-ems/members'><img src='https://gitee.com/liulingling1993/zhitan-ems/badge/fork.svg?theme=dark' alt='fork'></img></a>
</p>
## ä»‹ç»
通过物联网技术,采集企业水、电、气、热等能耗数据,帮企业建立能源管理体系,找到跑冒滴漏,从而为企业节能提供依据。
进一步为企业实现碳跟踪、碳盘查、碳交易、谈汇报的全生命过程。 ä¸ºä¸­å›½ç¢³è¾¾å³°-碳中和做出贡献。
能源管理系统,采集企业水、电、气、热等能耗数据,帮企业建立能源管理体系,找到跑冒滴漏,从而为企业节能提供依据。
进一步为企业实现碳跟踪、碳盘查、碳交易、碳汇报的全生命过程。 ä¸ºä¸­å›½ç¢³è¾¾å³°-碳中和做出贡献。
针对客户场景:政府、园区、企业、工矿、公共建筑等。
## ã€æ³¨æ„ã€‘完整能碳管理平台包含三个部分,<span style="color: red;">本仓库只包含能碳平台后台管理端</span>
##### 1. èƒ½ç¢³å¹³å°åŽå°ç®¡ç†ç«¯ï¼š<span style="color: red;">也即本项目能碳平台后台展示部分,代码完备,运行正常。通过本项目,学习者可以掌握能源管理行业的功能和业务,以及技术架构。</span>
##### 2. æ•°æ®é‡‡é›†ç¨‹åºï¼šä¹Ÿå³mqtt➡️时序库功能,请参考[我们另一个仓库(点击超链接),MQTT采集网关](https://github.com/zhitan-cloud/zhitan-gateway);或者可参考thingsjs等知名项目,或者自己用netty自己实现。
##### 3. æ•°æ®æ¸…洗服务:也即时序库➡️关系库,学习者可以使用java自带的XXL job等计划任务工具自己按照业务功能,来实现数据清洗服务。
墙内仓库地址(码云):https://gitee.com/ustcyc/zhitan-ems
## æ–‡æ¡£--均在wiki目录
### github wiki地址:https://github.com/zhitan-cloud/zhitan-ems/wiki
### gitee wiki地址:https://gitee.com/liulingling1993/zhitan-ems/wikis/
已同步更新到github仓库:https://github.com/Andy-Yin/zhitan-ems
## æ¡†æž¶ï¼š
基于SpringBoot的若依框架 æ˜“读易懂、界面简洁美观。
关系数据库:mysql æˆ–者 postgredb
时序数据库:influxdb 2.7+
中间件:redis,mq
VUE版本:VUE 3
## æ•°æ®é©±åŠ¨çš„è®¡ç®—æ¨¡åž‹å’Œä¸šåŠ¡æ¨¡åž‹é…ç½®
支持动态点位配置、数据模型、业务模型等。
## åœ¨çº¿ä½“验
- guestUser/guestUser
#### guestUser/guest@123456
#### æ¼”示地址:https://demo-ems.zhitancloud.com/
演示地址:https://demo-ems.zhitancloud.com/
## ç¤¾åŒºç‰ˆ-功能列表
1.  é¦–页看板 **已完成**
2.  å®žæ—¶æ•°æ®ç›‘测 **已完成**
    2.1.  å®žæ—¶æ•°æ®æŸ¥çœ‹ **已完成**
    2.2.  ç»„态图分析(svg å›¾ç»‘定)**已完成**
3. åŽ†å²ç‚¹ä½åˆ†æž **已完成**
4. ç»¼åˆæŒ‡æ ‡åˆ†æž **已完成**
   4.1.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆæ—¥ï¼‰**已完成**
   4.2.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆæœˆï¼‰**已完成**
   4.3.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆå¹´ï¼‰**已完成**
5. é‡ç‚¹è®¾å¤‡åˆ†æž  **已完成**
   5.1.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆæ—¥ï¼‰**已完成**
   5.2.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆæœˆï¼‰**已完成**
   5.3.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆå¹´ï¼‰**已完成**
6. å·¥åºèƒ½è€—分析 **已完成**
   6.1.  å·¥åºèƒ½è€—分析(日)**已完成**
   6.2.  å·¥åºèƒ½è€—分析(月)**已完成**
   6.3.  å·¥åºèƒ½è€—分析(年)**已完成**
7. å°–峰平谷分析 **已完成**
   7.1.  å°–峰平谷配置 **已完成**
   7.2.  å°–峰平谷数据 **已完成**
8. èƒ½è€—对比分析(各能源品种)**已完成**
   8.1.  ç”µåŒçŽ¯æ¯”åˆ†æž **已完成**
   8.2.  æ°´åŒçŽ¯æ¯”åˆ†æž **已完成**
   8.3.  å…¶ä»–能源品种分析 **已完成**
9. æ™ºèƒ½æŠ¥è­¦ **已完成**
   9.1.  æŠ¥è­¦åˆ†æž **已完成**
   9.2.  æŠ¥è­¦é…ç½® **已完成**
10. æ•°æ®è¡¥å½• **已完成**
11. èŠ‚èƒ½é¡¹ç›®ç®¡ç† **已完成**
12. çŸ¥è¯†åº“ **已完成**
13. è®¾å¤‡æ¡£æ¡ˆç®¡ç† **已完成**
14. æ¨¡åž‹é…ç½®ç®¡ç†ï¼ˆè®¡ç®—模型等) **已完成**
15. åŸºç¡€æ•°æ®ç®¡ç†ï¼ˆå­—典、能源类型等) **已完成**
16. ç³»ç»Ÿç®¡ç†ï¼ˆç”¨æˆ·ã€è§’色、权限等) **已完成**
17. å»ºç­‘能耗分析(支路、分项) **已完成**
## å¢žå¼ºç‰ˆ-功能列表
1. å•耗分析
2. è®¡åˆ’与实绩
3. ç”¨èƒ½è€ƒæ ¸
4. ç”¨èƒ½å¯¹æ ‡
5. å»ºç­‘能耗空调节能
6. èƒ½æºå¹³è¡¡åˆ†æž
7. èƒ½æºå¯¹æ ‡åˆ†æž
8. ç©ºåŽ‹æœºé‡ç‚¹è®¾å¤‡èŠ‚èƒ½å†…å®¹
9. ç¢³ç›˜æŸ¥ã€ç¢³è·¯å¾„、碳排放因子因子相关内容
10. æºç½‘荷储(微电网)相关功能
11. ä½Žç¢³å›­åŒºç›¸å…³
12. è‡ªå®šä¹‰æŠ¥è¡¨
13. èƒ½æºæˆæœ¬åˆ†æž
14. å…‰ä¼è¿ç»´ç›‘控
15. å……电运营平台
## æ¡†æž¶ï¼š
基于SpringBoot的若依框架 æ˜“读易懂、界面简洁美观。支持深色&浅色两种风格切换(演示系统右上角)
关系数据库:postgresql(mysql需自行适配,mysql性能太差了)
时序数据库:influxdb 2.7+
中间件:redis
VUE版本:VUE 3
## ç‰¹è‰²ï¼šæ•°æ®é©±åŠ¨çš„è®¡ç®—æ¨¡åž‹å’Œä¸šåŠ¡æ¨¡åž‹é…ç½®
1.  æ”¯æŒåŠ¨æ€ç‚¹ä½é…ç½®ã€‚
![输入图片说明](readme/img/指标配置.png)
2.  æ”¯æŒè®¡ç®—公式。
![输入图片说明](readme/img/计算公式.png)
3.  æ”¯æŒæ¨¡åž‹é…ç½®ã€åŒ…括数据模型、业务模型。
![输入图片说明](readme/img/模型配置.png)
4.  å¤æ‚项目底层代码&数据结构完全不需要变化,可快速交付实施。
5.  å·²å®Œæˆæ ‡å‡†åŒ–的网关&电表等采集设备对接,快速为客户软硬件一体化交付。
## äº®ç‚¹åŠŸèƒ½
![输入图片说明](readme/亮点功能.png)
## åŠŸèƒ½åˆ—è¡¨
1.  é¦–页看板
2.  å®žæ—¶æ•°æ®ç›‘测
    2.1.  å®žæ—¶æ•°æ®æŸ¥çœ‹
    2.2.  ç»„态图分析(svg å›¾ç»‘定)
3. åŽ†å²æ•°æ®åˆ†æž
4. ç»¼åˆæŒ‡æ ‡åˆ†æž
   4.1.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆæ—¥ï¼‰
   4.2.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆæœˆï¼‰
   4.3.  ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆå¹´ï¼‰
5. é‡ç‚¹è®¾å¤‡åˆ†æž
   5.1.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆæ—¥ï¼‰
   5.2.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆæœˆï¼‰
   5.3.  é‡ç‚¹è®¾å¤‡åˆ†æžï¼ˆå¹´ï¼‰
6. å·¥åºèƒ½è€—分析
   6.1.  å·¥åºèƒ½è€—分析(日)
   6.2.  å·¥åºèƒ½è€—分析(月)
   6.3.  å·¥åºèƒ½è€—分析(年)
7. å°–峰平谷分析
   7.1.  å°–峰平谷配置
   7.2.  å°–峰平谷数据
8. èƒ½è€—对比分析(各能源品种)
   8.1.  ç”µåŒçŽ¯æ¯”åˆ†æž
   8.2.  æ°´åŒçŽ¯æ¯”åˆ†æž
9. æ™ºèƒ½æŠ¥è­¦
   9.1.  æŠ¥è­¦åˆ†æž
   9.2.  æŠ¥è­¦é…ç½®
10. å•耗分析
11. è®¡åˆ’与实绩
12. ç”¨èƒ½è€ƒæ ¸
13. ç”¨èƒ½å¯¹æ ‡
14. æ•°æ®è¡¥å½•
15. èŠ‚èƒ½é¡¹ç›®ç®¡ç†
16. èƒ½æºå¹³è¡¡åˆ†æž
17. èƒ½æºå¯¹æ ‡åˆ†æž
18. æ¨¡åž‹é…ç½®ç®¡ç†ï¼ˆè®¡ç®—模型等)
19. åŸºç¡€æ•°æ®ç®¡ç†ï¼ˆå­—典、能源类型等)
20. ç³»ç»Ÿç®¡ç†ï¼ˆç”¨æˆ·ã€è§’色、权限等)
## UI展示(平台分深色和浅色两种风格切换)
@@ -107,10 +142,24 @@
## ä¸šåŠ¡æž¶æž„
![输入图片说明](readme/业务架构.png)
## æŠ€æœ¯æž¶æž„
![输入图片说明](readme/技术架构-1.png)
![输入图片说明](readme/技术架构.png)
## æ²Ÿé€šäº¤æµ
应很多开发者私信,我创建了QQ群交流,群号:,请备注:ems+姓名。
<p align="center">
  <img src="readme/img/qq.png" width=50% height=50%>
</p>
扫码添加微信交流,加微信请备注:ems+姓名。
<p align="center">
  <img src="readme/img/image-wxm.png" width=50% height=50%>
</p>
## å‚与贡献
1.  Fork æœ¬ä»“库
package-lock.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
{
  "name": "zhitan-ems",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {}
}
pom.xml
@@ -6,7 +6,7 @@
    <groupId>com.zhitan</groupId>
    <artifactId>BaseAdminAPI</artifactId>
    <version>3.8.7</version>
    <version>2.5.2</version>
    <name>BaseAdminAPI</name>
    <description>管理系统</description>
@@ -14,7 +14,7 @@
    <packaging>pom</packaging>
    <properties>
        <zhitan.version>3.8.7</zhitan.version>
        <zhitan.version>2.5.2</zhitan.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
readme/img/1-µÇ¼ҳ.png

readme/img/2-1-Ê×Ò³-dzɫ.png

readme/img/2-2-Ê×Ò³-ÉîÉ«.png

readme/img/3-1-ÄÜԴʵʱ¼à²â-dzɫ.png

readme/img/3-2-ÄÜԴʵʱ¼à²â-ÉîÉ«.png

readme/img/4-1-·åƽ¹Èʱ¶Îͳ¼Æ-dzɫ.png

readme/img/4-2-·åƽ¹Èʱ¶Îͳ¼Æ-ÉîÉ«.png

readme/img/5-1-ÇøÓòÄܺķÖÎö-dzɫ.png

readme/img/5-2-ÇøÓòÄܺķÖÎö-ÉîÉ«.png

readme/img/image-wxm.png
readme/img/image-yc.png
readme/img/image-zhuoyue.png
readme/img/qq.png
readme/img/Ö¸±êÅäÖÃ.png
readme/img/Ä£ÐÍÅäÖÃ.png
readme/img/ͳ¼ÆÖ¸±ê.png
readme/img/¼ÆË㹫ʽ.png
readme/logo-chinese.png
sql/postgre.sql
ÎļþÌ«´ó
sql/zhitan-ems_20250325182628.nb3
Binary files differ
zhitan-admin/pom.xml
@@ -4,8 +4,8 @@
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <version>2.5.2</version>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
zhitan-admin/src/.DS_Store
Binary files differ
zhitan-admin/src/main/java/com/zhitan/web/controller/branchanalysis/BranchEnergyAnalysisController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.zhitan.web.controller.branchanalysis;
import com.zhitan.branchanalysis.domain.BranchAnalysisVO;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.branchanalysis.service.IBranchAnalysisService;
import com.zhitan.realtimedata.domain.dto.BranchAnalysisDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.RestController;
/**
 *支路用能分析
 *
 * @author zt
 * @date 2025-03-26
 */
@RestController
@RequestMapping("/branchanalysis")
@Api(value = "支路用能能耗统计",tags = {"支路用能分析"})
public class BranchEnergyAnalysisController extends BaseController {
    @Autowired
    private IBranchAnalysisService branchAnalysisService;
    @GetMapping("/list")
    @ApiOperation(value = "支路用能能耗统计列表")
    public AjaxResult list(BranchAnalysisDTO dataItem)  {
        BranchAnalysisVO vo = branchAnalysisService.getBranchAnalysisService(dataItem);
        return success(vo);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/ComprehensiveStatisticsController.java
@@ -9,6 +9,7 @@
import com.zhitan.keyequipment.service.IDailyKeyEquipmentService;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.service.IModelNodeService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/DailyComprehensiveController.java
@@ -67,7 +67,7 @@
                i++;
            }
            List<DailyComprehensive> list = dailyComprehensiveService.getDailyComprehensiveList(modelNode.getNodeId(),
                    dataList, dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getIndexStorageId());
                    dataList, dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
            return AjaxResult.success(list);
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
@@ -87,7 +87,7 @@
        dataItem.setBeginTime(dataItem.getDataTime());
        String endTime=aa+" 24:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<DailyComprehensive> list = dailyComprehensiveService.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
        List<DailyComprehensive> list = dailyComprehensiveService.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/MonthlyComprehensiveController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
package com.zhitan.web.controller.comprehensivestatistics;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import com.zhitan.comprehensivestatistics.service.ImonthlyComprehensive;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.realtimedata.domain.DataItem;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
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.RestController;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * electricityPriceController
 *
 * @author sys
 * @date 2020-02-18
 */
@Slf4j
@RestController
@RequestMapping("/comprehensive/monthlyComprehensive")
@Api(value = "综合指标分析(月)controller",tags = {"综合指标分析"})
public class MonthlyComprehensiveController extends BaseController {
    @Autowired
    private IModelNodeService modelNodeService;
    @Autowired
    private ImonthlyComprehensive monthlyComprehensive;
    /*全厂能耗统计*/
    @ApiOperation(value = "获取综合指标分析(月)列表")
    @GetMapping("/list")
    public AjaxResult list(DataItem dataItem) {
        try {
            Map tableColumn =new HashMap<>();//表数据
            List<MonthlyComprehensive> dataList=new ArrayList<>();
            DateFormat df = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String aa= df.format(dataItem.getDataTime());
            String bb="";
            int i = 1;
            String beginTime=aa+"-01 00:00:00";
            dataItem.setBeginTime(sf.parse(beginTime));
            String endTime=aa+"-"+Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length()-2))+" 00:00:00";
            dataItem.setEndTime(sf.parse(endTime));
            while (i <= Integer.parseInt(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2))) {
                if (i > 9) {
                    bb = aa + "-" + i + " 00:00:00";
                } else {
                    bb = aa + "-0" + i + " 00:00:00";
                }
                MonthlyComprehensive report = new MonthlyComprehensive();
                report.setDataTime(sf.parse(bb));
                report.setValue("value" + i);
                dataList.add(report);
                tableColumn.put("value" + i, String.valueOf(i) + "日");
                i++;
            }
            MonthlyComprehensive reportList = new MonthlyComprehensive();
            List<Map> table = new ArrayList<>();
            table.add(tableColumn);
            reportList.setTablehead(table);
            ModelNode modelNode = modelNodeService.getModelNodeByModelCodeByIndexCode(dataItem.getIndexCode());
            if (ObjectUtils.isEmpty(modelNode)) {
                return AjaxResult.success(reportList);
            }
            List<MonthlyComprehensive> list = monthlyComprehensive.getMonthlyComprehensiveList(modelNode.getNodeId(),
                    dataList, dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
            int count = Integer.parseInt(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2));
            list.forEach(monthlyReport -> monthlyReport.setCount(count));
            reportList.setTabledata(list);
            return AjaxResult.success(reportList);
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
    }
/**/
    /**
     * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡å›¾
     */
    @GetMapping("/listChart")
    @ApiOperation(value = "获取综合指标分析图表(月)数据")
    public AjaxResult listChart(DataItem dataItem) throws ParseException {
        DateFormat df = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa= df.format(dataItem.getDataTime());
        String beginTime=aa+"-01 00:00:00";
        dataItem.setBeginTime(sf.parse(beginTime));
        String endTime=aa+"-"+Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length()-2))+" 00:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<MonthlyComprehensive> list = monthlyComprehensive.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
    public static String getLastDayOfMonth(String yearMonth) {
        int year = Integer.parseInt(yearMonth.split("-")[0]);  //å¹´
        int month = Integer.parseInt(yearMonth.split("-")[1]); //月
        Calendar cal = Calendar.getInstance();
        // è®¾ç½®å¹´ä»½
        cal.set(Calendar.YEAR, year);
        // è®¾ç½®æœˆä»½
        // cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.MONTH, month); //设置当前月的上一个月
        // èŽ·å–æŸæœˆæœ€å¤§å¤©æ•°
        //int lastDay = cal.getActualMaximum(Calendar.DATE);
        int lastDay = cal.getMinimum(Calendar.DATE); //获取月份中的最小值,即第一天
        // è®¾ç½®æ—¥åŽ†ä¸­æœˆä»½çš„æœ€å¤§å¤©æ•°
        //cal.set(Calendar.DAY_OF_MONTH, lastDay);
        cal.set(Calendar.DAY_OF_MONTH, lastDay - 1); //上月的第一天减去1就是当月的最后一天
        // æ ¼å¼åŒ–日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }
    /*综合月报表导出*/
//    @Log(title = "综合月报表导出", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    @ApiOperation(value = "综合月报表导出")
    public AjaxResult export(DataItem dataItem) {
        try {
            Map tableColumn =new HashMap<>();//表数据
            List<MonthlyComprehensive> dataList=new ArrayList<>();
            DateFormat df = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String aa= df.format(dataItem.getDataTime());
            String bb="";
            int i = 1;
            String beginTime=aa+"-01 00:00:00";
            dataItem.setBeginTime(sf.parse(beginTime));
            String endTime=aa+"-"+Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length()-2))+" 00:00:00";
            dataItem.setEndTime(sf.parse(endTime));
            while (i <= Integer.parseInt(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2))) {
                if (i > 9) {
                    bb = aa + "-" + i + " 00:00:00";
                } else {
                    bb = aa + "-0" + i + " 00:00:00";
                }
                MonthlyComprehensive report = new MonthlyComprehensive();
                report.setDataTime(sf.parse(bb));
                report.setValue("value" + i);
                dataList.add(report);
                tableColumn.put("value" + i, i + "日");
                i++;
            }
            MonthlyComprehensive reportList = new MonthlyComprehensive();
            List<Map> table = new ArrayList<>();
            table.add(tableColumn);
            reportList.setTablehead(table);
            ModelNode modelNode = modelNodeService.getModelNodeByModelCodeByIndexCode(dataItem.getIndexCode());
            if (ObjectUtils.isEmpty(modelNode)) {
                return AjaxResult.success(reportList);
            }
            List<MonthlyComprehensive> list = monthlyComprehensive.getMonthlyComprehensiveList(modelNode.getNodeId(), dataList,
                    dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
            int count = Integer.parseInt(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2));
            list.forEach(monthlyReport -> monthlyReport.setCount(count));
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(this::valueRep);
            }
            ExcelUtil<MonthlyComprehensive> util = new ExcelUtil<>(MonthlyComprehensive.class);
            return util.exportExcel(list, "综合指标分析月");
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
    }
    public void valueRep(Object dr){
        Field[] fields = dr.getClass().getDeclaredFields();
        for(Field field:fields){
            field.setAccessible(true);
            Object obj = field.getType();
            if(field.getType().getName().equals("java.lang.Double")){
                String name = field.getName();
                try {
                    if(ObjectUtils.isEmpty(field.get(dr)))
                    {
                        field.set(dr,0.00);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/comprehensivestatistics/YearComprehensiveController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
package com.zhitan.web.controller.comprehensivestatistics;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import com.zhitan.comprehensivestatistics.service.IyearComprehensive;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.realtimedata.domain.DataItem;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
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.RestController;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
 * electricityPriceController
 *
 * @author sys
 * @date 2020-02-18
 */
@RestController
@RequestMapping("/comprehensive/yearComprehensive")
@Api(value = "综合指标分析(年)controller",tags = {"综合指标分析"})
public class YearComprehensiveController extends BaseController {
    @Autowired
    private IModelNodeService modelNodeService;
    @Autowired
    private IyearComprehensive yearComprehensive;
    /*全厂能耗统计*/
    @GetMapping("/list")
    @ApiOperation(value = "获取综合指标分析(年)列表")
    public AjaxResult list(DataItem dataItem) {
        try {
            ModelNode modelNode = modelNodeService.getModelNodeByModelCodeByIndexCode(dataItem.getIndexCode());
            if (ObjectUtils.isEmpty(modelNode)) {
                return AjaxResult.success("暂无数据");
            }
            List<YearComperhensive> dataList = new ArrayList<>();
            dataItem.setBeginTime(DateUtil.beginOfYear(dataItem.getDataTime()));
            dataItem.setEndTime(DateUtil.endOfYear(dataItem.getDataTime()));
            DateFormat df = new SimpleDateFormat("yyyy");
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String aa = df.format(dataItem.getDataTime());
            String bb = "";
            int i = 1;
            while (i <= 12) {
                if(i > 9){
                    bb = aa + "-" + i + "-01 00:00:00";
                }else{
                    bb = aa + "-0" + i + "-01 00:00:00";
                }
                YearComperhensive report = new YearComperhensive();
                report.setDataTime(sf.parse(bb));
                report.setValue("value" + i);
                dataList.add(report);
                i++;
            }
            List<YearComperhensive> list = yearComprehensive.getYearComprehensiveList(modelNode.getNodeId(),
                    dataList,dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
            return AjaxResult.success(list);
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
    }
    /**
     * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡å›¾
     */
    @GetMapping("/listChart")
    @ApiOperation(value = "获取综合指标分析图表(年)数据")
    public AjaxResult listChart(DataItem dataItem){
        dataItem.setBeginTime(DateUtil.beginOfYear(dataItem.getDataTime()));
        dataItem.setEndTime(DateUtil.endOfYear(dataItem.getDataTime()));
        List<YearComperhensive> list = yearComprehensive.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
    /**
     * å¯¼å‡ºå·¥åºå•耗统计指标设置功能列表
     */
    @Log(title = "综合报表", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    @ApiOperation(value = "综合年报表导出")
    public AjaxResult export(DataItem dataItem) {
        try {
            ModelNode modelNode = modelNodeService.getModelNodeByModelCodeByIndexCode(dataItem.getIndexCode());
            if (ObjectUtils.isEmpty(modelNode)) {
                return AjaxResult.success("暂无数据");
            }
            List<YearComperhensive> dataList = new ArrayList<>();
            DateFormat df = new SimpleDateFormat("yyyy");
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String aa = df.format(dataItem.getBeginTime());
            String bb = "";
            int i = 1;
            while (i <= 12) {
                if(i>9){
                    bb=aa+"-"+i+"-01 00:00:00";
                }else{
                    bb=aa+"-0"+i+"-01 00:00:00";
                }
                YearComperhensive report=new YearComperhensive();
                report.setDataTime(sf.parse(bb));
                report.setValue("value"+i);
                dataList.add(report);
                i++;
            }
            List<YearComperhensive> list = yearComprehensive.getYearComprehensiveList(modelNode.getNodeId(),
                    dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
            if(CollectionUtils.isNotEmpty(list)){
                list.forEach(this::valueRep);
            }
            ExcelUtil<YearComperhensive> util = new ExcelUtil<>(YearComperhensive.class);
            return util.exportExcel(list, "综合指标分析年");
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
    }
    public void valueRep(Object dr){
        Field[] fields = dr.getClass().getDeclaredFields();
        for(Field field:fields){
            field.setAccessible(true);
            Object obj = field.getType();
            if(field.getType().getName().equals("java.lang.Double")){
                String name = field.getName();
                try {
                    if(ObjectUtils.isEmpty(field.get(dr)))
                    {
                        field.set(dr,0.00);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/consumptionanalysis/ConsumptionAnalysisController.java
@@ -10,6 +10,7 @@
import com.zhitan.consumptionanalysis.domain.vo.RankingDataVO;
import com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData;
import com.zhitan.consumptionanalysis.service.IConsumptionAnalysisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@@ -35,6 +36,7 @@
 * @Author: Zhujw
 * @Date: 2023/3/1
 */
@Api(tags = "综合能耗分析")
@RestController
@RequestMapping("/consumptionanalysis")
public class ConsumptionAnalysisController extends BaseController {
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricLoadController.java
@@ -5,6 +5,7 @@
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.energyMonitor.domain.vo.ListElectricLoadVO;
import com.zhitan.energyMonitor.domain.vo.ListElectricityMeterVO;
import com.zhitan.energyMonitor.service.IElectricLoadService;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.service.IEnergyIndexService;
@@ -16,6 +17,8 @@
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;
/**
 * @Description: è´Ÿè·åˆ†æž
@@ -50,7 +53,15 @@
                           @RequestParam(name = "timeCode") String timeCode) {
        EnergyIndex energyIndex = energyIndexService.getDeviceIndexByCode(nodeId, meterId, CommonConst.TAG_CODE_ZYGGL);
        ListElectricLoadVO vo = electricLoadService.list(timeType, timeCode, energyIndex);
        ListElectricLoadVO vo = electricLoadService.list(timeType, timeCode, energyIndex, meterId);
        return AjaxResult.success(vo);
    }
    @Log(title = "获取节点下所有电表")
    @ApiOperation(value = "获取节点下所有电表", notes = "获取节点下所有电表")
    @GetMapping(value = "/listElectricMeter")
    public AjaxResult listElectricMeter(@RequestParam(name = "nodeId") String nodeId) {
        List<ListElectricityMeterVO> vo = electricLoadService.listElectricMeter(nodeId);
        return AjaxResult.success(vo);
    }
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricThreePhaseController.java
@@ -56,6 +56,7 @@
        if (ObjectUtils.isEmpty(meterId)){
            return AjaxResult.error("电表id不能为空");
        }
        List<EnergyIndex> energyIndexList = energyIndexService.listDeviceIndex(nodeId, meterId);
        return AjaxResult.success(electricThreePhaseService.list(timeType, timeCode, energyIndexList, requestType, meterId));
zhitan-admin/src/main/java/com/zhitan/web/controller/energydatastatistics/EnergyDataStatisticsController.java
@@ -19,7 +19,7 @@
import java.util.List;
/**
 * æ’邦能源数据综合分析
 * èƒ½æºæ•°æ®ç»¼åˆåˆ†æž
 *
 * @author ZhiTan
 * @date 2024-10-30
zhitan-admin/src/main/java/com/zhitan/web/controller/history/HistoryDataTrendController.java
@@ -4,10 +4,15 @@
import com.zhitan.basicdata.domain.MeterImplement;
import com.zhitan.basicdata.services.IMeterImplementService;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.ChartUtils;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.history.domain.dto.HistoricalDataDTO;
import com.zhitan.history.domain.vo.HistoricalDataExcel;
@@ -16,7 +21,9 @@
import com.zhitan.model.service.IEnergyIndexService;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -29,11 +36,12 @@
import java.util.List;
/**
 * è®¾å¤‡å¯åœå®žæ—¶ç›‘测Controller
 * åŽ†å²æ•°æ®è¶‹åŠ¿Controller
 *
 * @author sys
 * @date 2020-03-30
 */
@Api(tags = "历史数据趋势")
@RestController
@RequestMapping("/dataMonitoring/historyDataTrend")
public class HistoryDataTrendController extends BaseController {
@@ -61,9 +69,6 @@
    public AjaxResult getSettingIndex(EnergyIndex energyIndex) {
        try {
            List<EnergyIndex> infoList = energyIndexService.selectEnergyIndexList(energyIndex);
//            List<String> codeList= infoList.stream().map(EnergyIndex::getCode).collect(Collectors.toList());
//            List<TagValue> valList = realtimeDatabaseService.retrieve(codeList);
//            List resultList = new ArrayList();
            return AjaxResult.success(infoList);
        } catch (Exception ex) {
            logger.error("获取关联采集指标出错!", ex);
@@ -80,68 +85,44 @@
            if (ObjectUtils.isEmpty(energyIndex)) {
                return AjaxResult.error("未找到点位信息");
            }
            Date beginTime = dto.getDataTime();
            Date endTime;
            // æŸ¥è¯¢æ¡æ•°
            int count = 1440;
            if ("DAY".equals(dto.getTimeType())) {
                endTime = DateUtil.endOfDay(beginTime);
            List<Date> dateList = new ArrayList<>();
            if (TimeType.DAY.name().equals(dto.getTimeType())) {
                String timeCode = DateTimeUtil.getDateTime(dto.getDataTime(), DateTimeUtil.COMMON_PATTERN_TO_DAY);
                ChartUtils.generateDateList(TimeTypeConst.TIME_TYPE_DAY, timeCode, dateList);
            } else if (TimeType.HOUR.name().equals(dto.getTimeType())) {
                String timeCode = DateTimeUtil.getDateTime(dto.getDataTime(), DateTimeUtil.COMMON_PATTERN_TO_HOUR);
                ChartUtils.generateDateList(TimeTypeConst.TIME_TYPE_HOUR, timeCode, dateList);
            } else {
                count = 3600;
                endTime = DateUtil.offsetSecond(DateUtil.offsetHour(beginTime, 1), -1);
                return AjaxResult.error("时间间隔类型不正确");
            }
            // æŸ¥è¯¢è®¡é‡å™¨å…·
            MeterImplement info = meterImplementService.selectMeterImplementById(energyIndex.getMeterId());
            List<TagValue> tagValueList = realtimeDatabaseService.retrieve(energyIndex.getCode(), beginTime, endTime,
                    RetrievalModes.BestFit, count);
            MeterImplement meterInfo = meterImplementService.selectMeterImplementById(energyIndex.getMeterId());
            if (ObjectUtils.isEmpty(meterInfo)) {
                return AjaxResult.error("未找到计量器具信息");
            }
            List<HistoricalDataVO> voList = new ArrayList<>();
            Date date = DateUtil.date();
            for (int i = 0; i < count + 1; i++) {
            for (Date date : dateList) {
                List<TagValue> tagValues = new ArrayList<>();
                if(TimeType.DAY.name().equals(dto.getTimeType())){
                    Date beginTime = date;
                    Date endTime = DateUtil.offsetHour(DateUtil.offsetMinute(date, CommonConst.DIGIT_MINUS_1), CommonConst.DIGIT_1);
                    tagValues = realtimeDatabaseService.retrieve(energyIndex.getCode(), beginTime,endTime,CommonConst.DIGIT_1);
                }
                if(TimeType.HOUR.name().equals(dto.getTimeType())){
                    Date beginTime = date;
                    Date endTime = DateUtil.offsetMinute(DateUtil.offsetSecond(date, CommonConst.DIGIT_MINUS_1), CommonConst.DIGIT_1);
                    tagValues = realtimeDatabaseService.retrieve(energyIndex.getCode(), beginTime,endTime,CommonConst.DIGIT_1);
                }
                HistoricalDataVO vo = new HistoricalDataVO();
                vo.setDataTime(DateUtil.formatDateTime(date));
                vo.setIndexId(energyIndex.getIndexId());
                String indexName = energyIndex.getName();
                if (ObjectUtils.isNotEmpty(info)) {
                    indexName = info.getInstallactionLocation() + "_" + info.getMeterName() + "_" + indexName;
                }
                vo.setIndexName(indexName);
                // å–值
                String value = "--";
                String usedValue = "--";
                if (beginTime.getTime() <= date.getTime()) {
                    try {
                        TagValue tagValue = tagValueList.get(i);
                        BigDecimal cumulative = BigDecimal.valueOf(tagValue.getValue());
                        if ("SWWSDJ_SD".equals(energyIndex.getCode()) || "SWWSDJ_WD".equals(energyIndex.getCode())) {
                            cumulative = cumulative.multiply(BigDecimal.valueOf(0.1));
                        }
                        if (i > 0) {
                            TagValue previousTagValue = tagValueList.get(i - 1);
                            BigDecimal previousValue = BigDecimal.ZERO;
                            if (ObjectUtils.isNotEmpty(previousTagValue.getValue())) {
                                previousValue = BigDecimal.valueOf(previousTagValue.getValue());
                            }
                            if ("SWWSDJ_SD".equals(energyIndex.getCode()) || "SWWSDJ_WD".equals(energyIndex.getCode())) {
                                previousValue = previousValue.multiply(BigDecimal.valueOf(0.1));
                            }
                            usedValue = String.valueOf(cumulative.subtract(previousValue).setScale(2, RoundingMode.HALF_UP));
                vo.setIndexName(meterInfo.getInstallactionLocation() + "_" + meterInfo.getMeterName() + "_" + energyIndex.getName());
                vo.setValue(CommonConst.DOUBLE_MINUS_SIGN);
                if(ObjectUtils.isNotEmpty(tagValues)){
                    vo.setValue(tagValues.get(0).getValue().toString());
                        }
                        value = String.valueOf(cumulative.setScale(2, RoundingMode.HALF_UP));
                    } catch (Exception ignored) {
                    }
                }
                // æ—¶é—´
                String timeName = DateUtil.formatDateTime(beginTime);
                vo.setDataTime(timeName);
                if ("DAY".equals(dto.getTimeType())) {
                    beginTime = DateUtil.offsetMinute(beginTime, 1);
                } else {
                    beginTime = DateUtil.offsetSecond(beginTime, 1);
                }
                vo.setUsedValue(String.valueOf(usedValue));
                vo.setValue(String.valueOf(value));
                voList.add(vo);
            }
            return AjaxResult.success(voList);
zhitan-admin/src/main/java/com/zhitan/web/controller/itemizedenergyanalysis/ItemizedEnergyAnalysisController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.zhitan.web.controller.itemizedenergyanalysis;
import com.zhitan.Itemizedenergyanalysis.domain.VO.ItemizedEnergyAnalysisVO;
import com.zhitan.Itemizedenergyanalysis.dto.ItemizedEnergyAnalysisDTO;
import com.zhitan.Itemizedenergyanalysis.service.IItemizedEnergyAnalysisService;
import com.zhitan.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
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.RestController;
import static com.zhitan.common.core.domain.AjaxResult.success;
/**
 * åˆ†é¡¹ç”¨èƒ½åˆ†æž æŽ¥å£
 */
@RestController
@RequestMapping("/itemizedEnergyAnalysis")
@Api(value = "分项用能分析", tags = {"分项用能分析"})
public class ItemizedEnergyAnalysisController {
    @Autowired
    private IItemizedEnergyAnalysisService itemizedEnergyAnalysisService;
    /**
     *
     * @param dataItem
     * @return
     */
    @GetMapping("/list")
    private AjaxResult list(ItemizedEnergyAnalysisDTO dataItem) {
        ItemizedEnergyAnalysisVO list = itemizedEnergyAnalysisService.getItemizedEnergyAnalysisService(dataItem);
        return success(list);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/DailyKeyEquipmenteController.java
@@ -3,7 +3,6 @@
import com.zhitan.basicdata.domain.FacilityArchives;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.core.page.TableDataInfo;
import com.zhitan.keyequipment.domain.DailyKeyEquipment;
import com.zhitan.keyequipment.service.IDailyKeyEquipmentService;
import com.zhitan.model.domain.EnergyIndex;
@@ -43,14 +42,14 @@
    @GetMapping("/list")
    @ApiOperation(value = "重点设备能耗分析(日)列表")
    public TableDataInfo list(DataItem dataItem) throws ParseException {
    public AjaxResult list(DataItem dataItem) throws ParseException {
        List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
        if(CollectionUtils.isEmpty(nodeId)){
            return getDataTable(new ArrayList<>());
            return success(new ArrayList<>());
        }
        List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
        if(CollectionUtils.isEmpty(energyList)){
            return getDataTable(new ArrayList<>());
            return success(new ArrayList<>());
        }
        List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
        List<DailyKeyEquipment> dataList=new ArrayList<>();
@@ -74,9 +73,10 @@
            dataList.add(report);
            i++;
        };
        startPage();
        List<DailyKeyEquipment> list = dailykeyEquipment.getdailyKeyEquipmentList(indexIds, dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
        return getDataTable(list);
        List<DailyKeyEquipment> list = dailykeyEquipment.getdailyKeyEquipmentList(indexIds, dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return success(list);
    }
    @GetMapping("/listChart")
@@ -88,12 +88,12 @@
        dataItem.setBeginTime(dataItem.getDataTime());
        String endTime=aa+" 24:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<DailyKeyEquipment> list = dailykeyEquipment.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
        List<DailyKeyEquipment> list = dailykeyEquipment.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
    /*所有设备*/
    @GetMapping("/getFacilityArchives")
    @ApiOperation(value = "查询所有设备列表")
    @ApiOperation(value = "查询重点设备列表")
    public AjaxResult getFacilityArchives() {
        try {
            List<FacilityArchives> list=dailykeyEquipment.getFacilityArchives();
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/MonthlyKeyEquipmentController.java
@@ -1,7 +1,6 @@
package com.zhitan.web.controller.keyequipment;
import com.github.pagehelper.PageInfo;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.keyequipment.domain.MonthlyKeyEquipment;
@@ -42,8 +41,7 @@
    @GetMapping("/list")
    @ApiOperation(value = "重点设备能耗统计(月)列表")
    public AjaxResult list(DataItem dataItem) {
        try {
    public AjaxResult list(DataItem dataItem) throws ParseException {
            List<MonthlyKeyEquipment> dataList=new ArrayList<>();
            Map tableColumn =new HashMap<>();//表数据
@@ -75,26 +73,17 @@
            reportList.setTablehead(table);
            List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
            if(CollectionUtils.isEmpty(nodeId)){
                return AjaxResult.success(reportList);
            return success(new ArrayList<>());
            }
            List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
            if(CollectionUtils.isEmpty(energyList)){
                return AjaxResult.success(reportList);
            return success(new ArrayList<>());
            }
            List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
            startPage();
            List<MonthlyKeyEquipment> list = monthlyKeyEquipmentService.getMonthlyKeyEquipmentList(indexIds, dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
            int count=Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length()-2));
            list.forEach(monthlyReport -> monthlyReport.setCount(count));
            reportList.setTabledata(list);
            reportList.setTotal(new PageInfo(list).getTotal());
        List<MonthlyKeyEquipment> list = monthlyKeyEquipmentService.getMonthlyKeyEquipmentList(indexIds, dataList, dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
            return AjaxResult.success(reportList);
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
        return success(list);
    }
    @GetMapping("/listChart")
@@ -107,9 +96,10 @@
        dataItem.setBeginTime(sf.parse(beginTime));
        String endTime=aa+"-"+Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length()-2))+" 00:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<MonthlyKeyEquipment> list = monthlyKeyEquipmentService.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
        List<MonthlyKeyEquipment> list = monthlyKeyEquipmentService.getListChart(dataItem.getIndexId(), dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
    public static String getLastDayOfMonth(String yearMonth) {
        int year = Integer.parseInt(yearMonth.split("-")[0]);  //å¹´
        int month = Integer.parseInt(yearMonth.split("-")[1]); //月
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/YearKeyEquipmentController.java
@@ -1,14 +1,18 @@
package com.zhitan.web.controller.keyequipment;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.core.page.TableDataInfo;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.keyequipment.domain.YearKeyEquipment;
import com.zhitan.keyequipment.service.IYearKeyEquipmentService;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.realtimedata.domain.DataItem;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
@@ -17,13 +21,11 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 *重点设备能耗统计 å¹´
 *
@@ -42,43 +44,31 @@
    @GetMapping("/list")
    @ApiOperation(value = "重点设备能耗统计(年)列表")
    public TableDataInfo list(DataItem dataItem) throws ParseException {
    public AjaxResult list(DataItem dataItem) throws ParseException {
        List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
        if(CollectionUtils.isEmpty(nodeId)){
            return getDataTable(new ArrayList<>());
            return success(new ArrayList<>());
        }
        List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
        if(CollectionUtils.isEmpty(energyList)){
            return getDataTable(new ArrayList<>());
            return success(new ArrayList<>());
        }
        List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
        List<YearKeyEquipment> dataList=new ArrayList<>();
        DateFormat df = new SimpleDateFormat("yyyy");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa= df.format(dataItem.getBeginTime());
        String bb="";
        int i = 1;
        while (i <= 12) {
            if(i>9){
                bb=aa+"-"+i+"-01 00:00:00";
            }else{
                bb=aa+"-0"+i+"-01 00:00:00";
            }
            YearKeyEquipment report=new YearKeyEquipment();
            report.setDataTime(sf.parse(bb));
            report.setValue("value"+i);
            dataList.add(report);
            i++;
        }
        startPage();
        List<YearKeyEquipment> list = yearKeyEquipmentService.getYearKeyEquipmentList(indexIds, dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
        return getDataTable(list);
       Date convertTime = DateTimeUtil.getEndTimeByType(dataItem.getTimeType(),dataItem.getDataTime());
       DateTime beginTime = DateUtil.beginOfYear(convertTime);
       DateTime endTime = DateUtil.endOfYear(convertTime);
       List<TypeTime> typeTimeList = DateTimeUtil.getDateTimeList(dataItem.getTimeType(),convertTime);
        List<YearKeyEquipment> list = yearKeyEquipmentService.getYearKeyEquipmentList(indexIds, typeTimeList,beginTime,endTime, dataItem.getTimeType(),dataItem.getEnergyType());
        return success(list);
    }
    @GetMapping("/listChart")
    @ApiOperation(value = "重点设备能耗统计(年)图表")
    public AjaxResult listChart(DataItem dataItem){
        List<YearKeyEquipment> list = yearKeyEquipmentService.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getIndexStorageId());
    public AjaxResult listChart(DataItemQueryDTO queryDto){
        List<YearKeyEquipment> list = yearKeyEquipmentService.getListChart(queryDto);
        return AjaxResult.success(list);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/meter/MeterController.java
@@ -26,9 +26,8 @@
 * @Version: 1.0
 * @Since: JDK1.8
 */
@Slf4j
@Api("采集计量表数据管理")
@Slf4j
@RestController
@RequestMapping("/meters")
public class MeterController extends BaseController {
zhitan-admin/src/main/java/com/zhitan/web/controller/model/DaqTemplateController.java
@@ -70,9 +70,12 @@
    boolean isExist = daqTemplateService.dapHasExist(daqTemplate.getCode(), daqTemplate.getDeviceType());
    if (isExist) {
      return AjaxResult.error("相同设备类型下的参数编码不能重复!");
    } else {
      return toAjax(daqTemplateService.insertDaqTemplate(daqTemplate));
    }
    boolean isCodeExist = daqTemplateService.dapCodeHasExist(daqTemplate.getGatewayKey(), daqTemplate.getDeviceType());
    if (isCodeExist) {
      return AjaxResult.error("相同设备类型下的采集参数编码不能重复!");
    }
    return toAjax(daqTemplateService.insertDaqTemplate(daqTemplate));
  }
  /**
@@ -85,11 +88,13 @@
    boolean isExist = daqTemplateService.dapHasExist(daqTemplate);
    if (isExist) {
      return AjaxResult.error("相同设备类型下的参数编码不能重复!");
    } else {
    }
    boolean isCodeExist = daqTemplateService.dapCodeHasExist(daqTemplate);
    if (isCodeExist) {
      return AjaxResult.error("相同设备类型下的采集参数编码不能重复!");
    }
      return toAjax(daqTemplateService.updateDaqTemplate(daqTemplate));
    }
  }
  /**
   * åˆ é™¤é‡‡é›†å‚数模板
   */
zhitan-admin/src/main/java/com/zhitan/web/controller/model/EnergyIndexController.java
@@ -9,17 +9,21 @@
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.EnergyIndexQuery;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.service.IEnergyIndexService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * æŒ‡æ ‡ä¿¡æ¯Controller
@@ -122,29 +126,51 @@
  }
  /**
   * åˆ é™¤æŒ‡æ ‡ä¿¡æ¯
     * åˆ é™¤é‡‡é›†æŒ‡æ ‡ä¿¡æ¯
   */
  @PreAuthorize("@ss.hasPermi('energyindex:energyindex:remove')")
  @Log(title = "指标信息", businessType = BusinessType.DELETE)
  @DeleteMapping("/{nodeId}/{indexIds}")
  public AjaxResult remove(@PathVariable String nodeId, @PathVariable String[] indexIds) {
    List<EnergyIndex> energyIndexList = energyIndexService.getEnergyIndexByIds(
        Arrays.asList(indexIds));
    List<String> deleteIds = energyIndexList.stream()
        .filter(f -> StringUtils.isBlank(f.getMeterId()))
        .map(EnergyIndex::getIndexId)
        .collect(Collectors.toList());
    List<String> removeLink = energyIndexList.stream()
        .filter(f -> StringUtils.isNotBlank(f.getMeterId()))
        .map(EnergyIndex::getIndexId)
        .collect(Collectors.toList());
    if (!removeLink.isEmpty()) {
      energyIndexService.removeNodeIndex(nodeId, removeLink);
    @DeleteMapping("/{indexIds}")
    public AjaxResult remove(@PathVariable String[] indexIds) {
        List<String> indexIdList = Arrays.asList(indexIds);
        if (ObjectUtils.isEmpty(indexIdList)) {
            return AjaxResult.success();
        }
        // æŸ¥è¯¢æ¨¡åž‹èŠ‚ç‚¹ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfo> modelNodeIndexInfoList = energyIndexService.getModelNodeIndexInfoListByIndexIds(indexIds);
        if (ObjectUtils.isNotEmpty(modelNodeIndexInfoList)) {
            ModelNodeIndexInfo modelNodeIndexInfo = modelNodeIndexInfoList.stream().findFirst().get();
            return AjaxResult.error("采集指标 " + modelNodeIndexInfo.getIndexName() + " å·²è¢«æ¨¡åž‹ " + modelNodeIndexInfo.getModelName() + " å…³è”,不能删除!");
    }
    if (!deleteIds.isEmpty()) {
      energyIndexService.deleteEnergyIndexByIds(nodeId, deleteIds.toArray(new String[0]));
        energyIndexService.removeEnergyIndex(indexIdList);
        return AjaxResult.success();
    }
    /**
     * åˆ é™¤ç»Ÿè®¡æŒ‡æ ‡ä¿¡æ¯
     */
    @PreAuthorize("@ss.hasPermi('energyindex:energyindex:remove')")
    @Log(title = "指标信息", businessType = BusinessType.DELETE)
    @DeleteMapping("{nodeId}/{indexIds}")
    public AjaxResult remove(@PathVariable String nodeId, @PathVariable String[] indexIds) {
        List<String> indexIdList = Arrays.asList(indexIds);
        if (ObjectUtils.isEmpty(indexIdList)) {
            return AjaxResult.success();
        }
        // æŸ¥è¯¢æ¨¡åž‹èŠ‚ç‚¹ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfo> modelNodeIndexInfoList = energyIndexService.getModelNodeIndexInfoListByIndexIds(indexIds);
        if (ObjectUtils.isNotEmpty(modelNodeIndexInfoList)) {
            if(modelNodeIndexInfoList.size() > 1){
                return AjaxResult.error("该统计指标已被其他模型关联,不能删除!");
            }
        }
        energyIndexService.removeEnergyIndex(indexIdList);
    return AjaxResult.success();
  }
zhitan-admin/src/main/java/com/zhitan/web/controller/model/ModelInfoController.java
@@ -10,6 +10,7 @@
import com.zhitan.model.domain.vo.PointDataVO;
import com.zhitan.model.service.IEnergyIndexService;
import com.zhitan.model.service.IModelInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -23,6 +24,7 @@
 * @author fanxinfu
 * @date 2020-02-17
 */
@Api(tags = "模型相关")
@RestController
@RequestMapping("/basicsetting/model")
public class ModelInfoController extends BaseController {
zhitan-admin/src/main/java/com/zhitan/web/controller/peakvalley/PeakValleyController.java
@@ -60,8 +60,6 @@
    @ApiOperation(value = "获取尖峰平谷分时统计")
    public AjaxResult segmentAnalysisDay(PeakValleyDTO dto) {
        return AjaxResult.success(rulesService.segmentAnalysisDay(dto));
//        return AjaxResult.success(rulesService.segmentAnalysisDayCustomize(dto));
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/DailyProcessEnergyController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package com.zhitan.web.controller.processenergy;
import com.zhitan.basicdata.domain.FacilityArchives;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.processenergy.domain.DailyProcessEnergy;
import com.zhitan.processenergy.service.IDailyProcessEnergyService;
import com.zhitan.realtimedata.domain.DataItem;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
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.RestController;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * å·¥åºèƒ½è€— æ—¥
 */
@RestController
@RequestMapping("/processEnergy/dailyProcessEnergy")
@Api(value = "工序能耗统计(日)", tags = {"工序能耗统计"})
public class DailyProcessEnergyController extends BaseController {
    @Autowired
    private IModelNodeService modelNodeService;
    @Autowired
    private IDailyProcessEnergyService dailyProcessEnergy;
    @GetMapping("/list")
    @ApiOperation(value = "工序能耗统计(日)列表")
    public AjaxResult list(DataItem dataItem) throws ParseException{
        List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
        if(CollectionUtils.isEmpty(nodeId)){
            return success(new ArrayList<>());
        }
        List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
        if(CollectionUtils.isEmpty(energyList)){
            return success(new ArrayList<>());
        }
        List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
        List<DailyProcessEnergy> dataList = new ArrayList<>();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa= df.format(dataItem.getDataTime());
        String bb="";
        int i = 0;
        dataItem.setBeginTime(dataItem.getDataTime());
        String endTime=aa+" 24:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        while (i < 24) {
            if(i>9){
                bb=aa+" "+i+":00:00";
            }else{
                bb=aa+" 0"+i+":00:00";
            }
            DailyProcessEnergy report=new DailyProcessEnergy();
            report.setDataTime(sf.parse(bb));
            report.setValue("value"+i);
            dataList.add(report);
            i++;
        }
        List<DailyProcessEnergy> list = dailyProcessEnergy.getDailyProcessEnergyList(indexIds, dataList,dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return success(list);
    }
    @GetMapping("/listChart")
    @ApiOperation(value = "工序能耗(日)图表")
    public AjaxResult listChart(DataItem dataItem) throws ParseException {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa= df.format(dataItem.getDataTime());
        dataItem.setBeginTime(dataItem.getDataTime());
        String endTime=aa+" 24:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<DailyProcessEnergy> list = dailyProcessEnergy.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/MonthlyProcessEnergyController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
package com.zhitan.web.controller.processenergy;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.processenergy.domain.MonthlyProcessEnergy;
import com.zhitan.processenergy.service.IMonthlyProcessEnergyService;
import com.zhitan.realtimedata.domain.DataItem;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
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.RestController;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * å·¥åºèƒ½è€— æœˆ
 */
@RestController
@RequestMapping("/processEnergy/monthlyProcessEnergy")
@Api(value = "工序能耗统计(月)", tags = {"工序能耗统计"})
public class MonthlyProcessEnergyController extends BaseController {
    @Autowired
    private IModelNodeService modelNodeService;
    @Autowired
    private IMonthlyProcessEnergyService monthlyProcessEnergyService;
    /**
     *
     * @param dataItem
     * @return
     * @throws ParseException
     */
    @GetMapping("/list")
    @ApiOperation(value = "工序能耗统计(月)")
    public AjaxResult list(DataItem dataItem) throws ParseException {
        List<MonthlyProcessEnergy> dataList = new ArrayList<>();
        Map tableColumn = new HashMap<>();//表数据
        DateFormat df = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa = df.format(dataItem.getDataTime());
        String bb = "";
        int i = 1;
        String beginTime = aa + "-01 00:00:00";
        dataItem.setBeginTime(sf.parse(beginTime));
        String endTime = aa + "-" + Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2)) + " 00:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        while (i <= Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2))) {
            if (i > 9) {
                bb = aa + "-" + i + " 00:00:00";
            } else {
                bb = aa + "-0" + i + " 00:00:00";
            }
            MonthlyProcessEnergy report = new MonthlyProcessEnergy();
            report.setDataTime(sf.parse(bb));
            report.setValue("value" + i);
            dataList.add(report);
            tableColumn.put("value" + i, String.valueOf(i) + "日");
            i++;
        }
        List<Map> table = new ArrayList<>();
        MonthlyProcessEnergy reportList = new MonthlyProcessEnergy();
        table.add(tableColumn);
        reportList.setTablehead(table);
        List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
        if (CollectionUtils.isEmpty(nodeId)) {
            return success(new ArrayList<>());
        }
        List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
        if (CollectionUtils.isEmpty(energyList)) {
            return success(new ArrayList<>());
        }
        List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
        List<MonthlyProcessEnergy> list = monthlyProcessEnergyService.getMonthlyProcessEnergy(indexIds, dataList, dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
        return success(list);
    }
    /**
     *
     * @param dataItem
     * @return
     * @throws ParseException
     */
    @GetMapping("/listChart")
    @ApiOperation(value = "重点设备能耗统计(月)图表")
    public AjaxResult listChart(DataItem dataItem) throws ParseException {
        DateFormat df = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String aa = df.format(dataItem.getDataTime());
        String beginTime = aa + "-01 00:00:00";
        dataItem.setBeginTime(sf.parse(beginTime));
        String endTime = aa + "-" + Integer.valueOf(getLastDayOfMonth(aa).substring(getLastDayOfMonth(aa).length() - 2)) + " 00:00:00";
        dataItem.setEndTime(sf.parse(endTime));
        List<MonthlyProcessEnergy> list = monthlyProcessEnergyService.getListChart(dataItem.getIndexId(), dataItem.getBeginTime(), dataItem.getEndTime(), dataItem.getTimeType(), dataItem.getEnergyType());
        return AjaxResult.success(list);
    }
    /**
     *
     * @param yearMonth
     * @return
     */
    public static String getLastDayOfMonth(String yearMonth) {
        int year = Integer.parseInt(yearMonth.split("-")[0]);  //å¹´
        int month = Integer.parseInt(yearMonth.split("-")[1]); //月
        Calendar cal = Calendar.getInstance();
        // è®¾ç½®å¹´ä»½
        cal.set(Calendar.YEAR, year);
        // è®¾ç½®æœˆä»½
        // cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.MONTH, month); //设置当前月的上一个月
        // èŽ·å–æŸæœˆæœ€å¤§å¤©æ•°
        //int lastDay = cal.getActualMaximum(Calendar.DATE);
        int lastDay = cal.getMinimum(Calendar.DATE); //获取月份中的最小值,即第一天
        // è®¾ç½®æ—¥åŽ†ä¸­æœˆä»½çš„æœ€å¤§å¤©æ•°
        //cal.set(Calendar.DAY_OF_MONTH, lastDay);
        cal.set(Calendar.DAY_OF_MONTH, lastDay - 1); //上月的第一天减去1就是当月的最后一天
        // æ ¼å¼åŒ–日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(cal.getTime());
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/processenergy/YearProcessEnergyController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.zhitan.web.controller.processenergy;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.processenergy.domain.YearProcessEnergy;
import com.zhitan.processenergy.service.IYearProcessEnergyService;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
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.RestController;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * å·¥åºèƒ½è€— å¹´
 *
 *
 */
@RestController
@RequestMapping("/processEnergy/YearProcessEnergy")
@Api(value = "工序能耗统计(年)", tags = {"工序能耗统计"})
public class YearProcessEnergyController extends BaseController {
    @Autowired
    private IModelNodeService modelNodeService;
    @Autowired
    private IYearProcessEnergyService yearProcessEnergyService;
    @GetMapping("/list")
    @ApiOperation(value = "工序能耗统计(年)列表")
    private AjaxResult list(DataItemQueryDTO dataItem) throws ParseException{
        List<ModelNode> nodeId = modelNodeService.getModelNodeByModelCode(dataItem.getIndexCode());
        if(CollectionUtils.isEmpty(nodeId)){
            return success(new ArrayList<>());
        }
        List<EnergyIndex> energyList = modelNodeService.getSettingIndex(nodeId.get(0).getNodeId());
        if(CollectionUtils.isEmpty(energyList)){
            return success(new ArrayList<>());
        }
        List<String> indexIds = energyList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
        Date convertTime = DateTimeUtil.getTypeTime(dataItem.getTimeType(), dataItem.getDataTime());
        DateTime beginTime = DateUtil.beginOfYear(convertTime);
        DateTime endTime = DateUtil.endOfYear(convertTime);
        List<TypeTime> typeTimeList = DateTimeUtil.getDateTimeList(dataItem.getTimeType(),convertTime);
        List<YearProcessEnergy> list = yearProcessEnergyService.getYearProcessEnergy(indexIds, typeTimeList,beginTime,endTime, dataItem.getTimeType(),dataItem.getEnergyType());
        return success(list);
    }
    @GetMapping("/listChart")
    @ApiOperation(value = "工序能耗(年)图表")
    public AjaxResult listChart(DataItemQueryDTO queryDto) {
        List<YearProcessEnergy> list = yearProcessEnergyService.getListChart(queryDto);
        return AjaxResult.success(list);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/saving/EnergySavingProgramController.java
@@ -36,7 +36,7 @@
     * åˆ—表
     */
    @GetMapping("/page")
    @PreAuthorize("@ss.hasPermi('energySavingProject:list')")
    @PreAuthorize("@ss.hasPermi('energySavingProject:Project:list')")
    @ApiOperation(value = "分页列表")
    public TableDataInfo list(EnergySavingProgram energySavingProgram) {
        Page<EnergySavingProgramVO> list = energySavingProgramService.selectEnergySavingProgramList(energySavingProgram);
@@ -50,7 +50,6 @@
     * è¯¦ç»†ä¿¡æ¯
     */
    @ApiOperation(value = "查询详情")
    @PreAuthorize("@ss.hasPermi('energySavingProject')")
    @GetMapping(value = "getById")
    public AjaxResult getInfo(@RequestParam("id") Long id) {
        return success(energySavingProgramService.selectEnergySavingProgramById(id));
@@ -61,6 +60,7 @@
     * èŠ‚èƒ½é¡¹ç›®ç®¡ç†
     */
    @ApiOperation(value = "新增")
    @PreAuthorize("@ss.hasPermi('energySavingProject:Project:add')")
    @PostMapping("add")
    public AjaxResult add(  @RequestBody EnergySavingProgramDTO dto) {
        return energySavingProgramService.insertEnergySavingProgram(dto);
@@ -71,6 +71,7 @@
     * èŠ‚èƒ½é¡¹ç›®ç®¡ç†
     */
    @ApiOperation(value = "更新")
    @PreAuthorize("@ss.hasPermi('energySavingProject:Project:edit')")
    @PostMapping("edit")
    public AjaxResult edit(@RequestBody EnergySavingProgramDTO dto) {
        return energySavingProgramService.updateEnergySavingProgram(dto);
@@ -81,6 +82,7 @@
     * èŠ‚èƒ½é¡¹ç›®ç®¡ç†
     */
    @DeleteMapping("del/{id}")
    @PreAuthorize("@ss.hasPermi('energySavingProject:Project:del')")
    @ApiOperation(value = "删除")
    public AjaxResult remove(@PathVariable  Long id) {
        return energySavingProgramService.deleteEnergySavingProgramById(id);
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/EnergyConsumeDataController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.zhitan.web.controller.statisticalAnalysis;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.zhitan.statisticalAnalysis.service.IEnergyConsumeDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @Description: èƒ½æºæ¶ˆè€—统计分析
 * @author: yxw
 * @date: 2022å¹´04月12日 14:11
 */
@Api(tags = "能耗统计分析")
@RestController
@RequestMapping("/energyTypeAnalysis")
@Slf4j
public class EnergyConsumeDataController {
    @Autowired
    private IEnergyConsumeDataService energyConsumeDataService;
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®
     *
     * @param pageNo   é¡µç æ•°
     * @param pageSize æ¯é¡µæ•°æ®å¤šå°‘
     * @param timeCode æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param energyType èƒ½æºç±»åž‹
     * @param modelCode æ¨¡åž‹Code
     * @return
     */
    @Log(title = "能耗统计分析-成本趋势分析(能源消耗成本)- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®")
    @ApiOperation(value = "能耗统计分析-成本趋势分析(能源消耗成本)- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®", notes = "能耗统计分析-成本趋势分析(能源消耗成本)- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®")
    @GetMapping(value = "/listEnergyCostTrend")
    public AjaxResult listEnergyCostTrend(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                          @RequestParam(name = "timeCode") String timeCode,
                                          @RequestParam(name = "timeType") String timeType,
                                          @RequestParam(name = "energyType",required = false) String energyType,
                                          @RequestParam(name = "modelCode") String modelCode) {
        return AjaxResult.success(energyConsumeDataService.listEnergyCostTrend(pageNo, pageSize, timeCode, timeType,energyType,
                modelCode));
    }
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰
     *
     * @param timeCode æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param modelCode   æ¨¡åž‹Code
     * @param energyType èƒ½æºç±»åž‹
     * @return
     */
    @Log(title = "能耗统计分析-成本趋势分析(能源消耗成本)")
    @ApiOperation(value = "能耗统计分析-成本趋势分析(能源消耗成本)", notes = "能耗统计分析-成本趋势分析(能源消耗成本)")
    @GetMapping(value = "/listEnergyCostTrendDetail")
    public AjaxResult listEnergyCostTrendDetail(@RequestParam(name = "timeCode") String timeCode,
                                                                                @RequestParam(name = "timeType") String timeType,
                                                                                @RequestParam(name = "modelCode") String modelCode,
                                                                                @RequestParam(name = "energyType",required = false) String energyType) {
        return AjaxResult.success(energyConsumeDataService.listEnergyCostTrendDetail(timeCode, timeType, modelCode, energyType));
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/EnergyDataItemController.java
@@ -1,9 +1,12 @@
package com.zhitan.web.controller.statisticalAnalysis;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.dataitem.service.IDataItemService;
import com.zhitan.statisticalAnalysis.domain.dto.FlowChartsDTO;
import com.zhitan.statisticalAnalysis.domain.vo.QueryCompareRequest;
import com.zhitan.statisticalAnalysis.service.IEnergyConsumeDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +27,9 @@
    @Autowired
    private IDataItemService dataItemService;
    @Autowired
    private IEnergyConsumeDataService energyConsumeDataService;
    /**
     * èŽ·å–èƒ½æµå›¾å½¢åˆ†æž
     *
@@ -36,4 +42,28 @@
    public AjaxResult getFlowCharts(@Validated FlowChartsDTO dto) {
        return AjaxResult.success(dataItemService.getFlowCharts(dto));
    }
    @Log(title = "能耗统计分析-获取同比分析列表数据")
    @ApiOperation(value = "能耗统计分析-获取同比分析列表数据", notes = "能耗统计分析-获取同比分析列表数据")
    @GetMapping(value = "/querySameCompareList")
    public AjaxResult querySameCompareList(@Validated QueryCompareRequest queryCompareRequest) {
        return AjaxResult.success(energyConsumeDataService.listEnergyTypeYoyInfo(queryCompareRequest, CommonConst.ENERGY_COMPARISON_YOY));
    }
    /**
     * èŽ·å–çŽ¯æ¯”åˆ†æžæ•°æ®
     * <p>
     * é€šè¿‡è‡ªå·±çš„æœåŠ¡è®¿é—®åœ°å€ï¼šhttp://localhost:7005/fengniao/energyDataItem/queryLoopCompare?timeType=1
     * é€šè¿‡ç½‘关访问地址:http://localhost:9999/jeecg-fengniao/fengniao/energyDataItem/queryLoopCompare?timeType=1
     *
     * @param queryCompareRequest
     * @return
     */
    @Log(title = "能耗统计分析-获取环比分析列表数据")
    @ApiOperation(value = "能耗统计分析-获取环比分析列表数据", notes = "能耗统计分析-获取环比分析列表数据")
    @GetMapping(value = "/queryLoopCompareList")
    public AjaxResult queryLoopCompareList(@Validated QueryCompareRequest queryCompareRequest) {
        return AjaxResult.success(energyConsumeDataService.listEnergyTypeYoyInfo(queryCompareRequest, CommonConst.ENERGY_COMPARISON_MOM));
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java
@@ -9,6 +9,7 @@
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYExcel;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
import com.zhitan.statisticalAnalysis.service.IStatisticalAnalysisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
@@ -26,6 +27,7 @@
/**
 * ç»Ÿè®¡åˆ†æž æŽ§åˆ¶å±‚
 */
@Api(tags = "统计分析")
@RestController
@RequestMapping("/statisticalAnalysis")
public class StatisticalAnalysisController extends BaseController {
zhitan-admin/src/main/java/com/zhitan/web/controller/system/SysProfileController.java
@@ -1,5 +1,6 @@
package com.zhitan.web.controller.system;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@@ -43,6 +44,7 @@
     * ä¸ªäººä¿¡æ¯
     */
    @GetMapping
    @PreAuthorize("@ss.hasPermi('system:user:message')")
    public AjaxResult profile()
    {
        LoginUser loginUser = getLoginUser();
@@ -57,6 +59,7 @@
     * ä¿®æ”¹ç”¨æˆ·
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @PutMapping
    public AjaxResult updateProfile(@RequestBody SysUser user)
    {
@@ -87,6 +90,7 @@
     * é‡ç½®å¯†ç 
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(String oldPassword, String newPassword)
    {
zhitan-admin/src/main/java/com/zhitan/web/core/config/SwaggerConfig.java
@@ -115,11 +115,11 @@
        // ç”¨ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // è®¾ç½®æ ‡é¢˜
                .title("标题:后台管理系统_接口文档")
                .title("智碳_能源管理系统_接口文档")
                // æè¿°
                .description("描述:接口文档")
                .description("采集企业水、电、气、热等能耗数据;帮助企业建立能源管理体系,找到跑冒滴漏,为企业节能提供数据支撑;为企业实现碳跟踪、碳盘查、碳交易、碳汇报的全生命过程;为中国碳达峰-碳中和做出贡献!")
                // ä½œè€…信息
                .contact(new Contact(baseConfig.getName(), null, null))
                .contact(new Contact(baseConfig.getName(), "https://www.zhitancloud.com", "yin.cun@qq.com"))
                // ç‰ˆæœ¬
                .version("版本号:" + baseConfig.getVersion())
                .build();
zhitan-admin/src/main/resources/application-dev.yml
@@ -6,9 +6,9 @@
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:postgresql://127.0.0.1:5432/energy
        username: root
        password: 123456
          url: jdbc:postgresql://127.0.0.1:5432/zhitan_ems
          username: postgres
          password: postgres
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
zhitan-admin/src/main/resources/application.yml
@@ -3,7 +3,7 @@
  # åç§°
  name: admin
  # ç‰ˆæœ¬
  version: 3.8.7
  version: 2.5.2
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2024
  profile: ./uploadPath
@@ -146,6 +146,7 @@
  token: ==
  org: org
  bucket: bucket
  measurement: data
###################### MQTT #################################
mqtt:
zhitan-common/.DS_Store
Binary files differ
zhitan-common/pom.xml
@@ -5,7 +5,7 @@
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
        <version>2.5.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
zhitan-common/src/.DS_Store
Binary files differ
zhitan-common/src/main/java/com/zhitan/common/constant/CommonConst.java
@@ -867,7 +867,7 @@
    /**
     * æ€»æœ‰åŠŸåŠŸçŽ‡ç‚¹ä½æ¨¡æ¿code
     */
    public static final String TAG_CODE_ZYGGL = "\\_ActivePower_Total";
    public static final String TAG_CODE_ZYGGL = "ActivePow";
    /**
     * æ€»æœ‰åŠŸåŠŸçŽ‡ç‚¹ä½æ¨¡æ¿code
     */
@@ -887,19 +887,19 @@
    /**
     * æ€»åŠŸçŽ‡å› æ•° ç‚¹ä½æ¨¡æ¿code
     */
    public static final String TAG_CODE_GLYS = "PowerFactor_Total";
    public static final String TAG_CODE_GLYS = "PowFactorT";
    /**
     * ç”µæµ
     */
    public static final String TAG_CODE_CURRENT = "Current_";
    public static final String TAG_CODE_CURRENT = "Current";
    /**
     * ç”µåŽ‹
     */
    public static final String TAG_CODE_VOLTAGE = "Voltage_";
    public static final String TAG_CODE_VOLTAGE = "Voltage";
    /**
     * åŠŸçŽ‡å› æ•°
     */
    public static final String TAG_CODE_FACTOR = "PowerFactor_";
    public static final String TAG_CODE_FACTOR = "PowerFactor";
    /**
     * åŠŸçŽ‡å› æ•°
     */
@@ -935,27 +935,27 @@
    /**
     * A相电流
     */
    public static final String TAG_CODE_CURRENT_A = "Current_A";
    public static final String TAG_CODE_CURRENT_A = "CurrentA";
    /**
     * B相电流
     */
    public static final String TAG_CODE_CURRENT_B = "Current_B";
    public static final String TAG_CODE_CURRENT_B = "CurrentB";
    /**
     * C相电流
     */
    public static final String TAG_CODE_CURRENT_C = "Current_C";
    public static final String TAG_CODE_CURRENT_C = "CurrentC";
    /**
     * A相电压
     */
    public static final String TAG_CODE_VOLTAGE_A = "Voltage_A";
    public static final String TAG_CODE_VOLTAGE_A = "VoltageA";
    /**
     * B相电压
     */
    public static final String TAG_CODE_VOLTAGE_B = "Voltage_B";
    public static final String TAG_CODE_VOLTAGE_B = "VoltageB";
    /**
     * C相电压
     */
    public static final String TAG_CODE_VOLTAGE_C = "Voltage_C";
    public static final String TAG_CODE_VOLTAGE_C = "VoltageC";
    /**
     * A相功率因数
     */
zhitan-common/src/main/java/com/zhitan/common/core/domain/entity/SysDictType.java
@@ -37,6 +37,7 @@
    /** çŠ¶æ€ï¼ˆ0正常 1停用) */
    @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
    private String status;
    private String remark;
    public Long getDictId()
    {
@@ -97,4 +98,14 @@
            .append("remark", getRemark())
            .toString();
    }
    @Override
    public String getRemark() {
        return remark;
    }
    @Override
    public void setRemark(String remark) {
        this.remark = remark;
    }
}
zhitan-common/src/main/java/com/zhitan/common/enums/IndexType.java
@@ -4,9 +4,22 @@
  /**
   * é‡‡é›†æŒ‡æ ‡
   */
  COLLECT,
  COLLECT("COLLECT"),
  /**
   * ç»Ÿè®¡æŒ‡æ ‡
   */
  STATISTIC
  STATISTIC("STATISTIC");
  private final String description;
  IndexType(String description)
  {
    this.description = description;
  }
  public String getDescription()
  {
    return description;
  }
}
zhitan-common/src/main/java/com/zhitan/common/enums/RetrievalModes.java
@@ -6,5 +6,8 @@
 *     èŽ·å–å®žæ—¶æ•°æ®æ–¹å¼.
 */
public enum RetrievalModes {
  Full, BestFit
  Full,
  BestFit
}
zhitan-common/src/main/java/com/zhitan/common/utils/ChartUtils.java
@@ -24,6 +24,20 @@
    public static void generateDateList(String timeType, String timeCode, List<Date> dateList) {
        Date now = new Date();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                if (!timeCode.contains(CommonConst.SINGLE_MINUS_SIGN)) {
                    timeCode = DateTimeUtil.toDateTimeStr(timeCode, DateTimeUtil.COMMON_PATTERN_HOUR, DateTimeUtil.COMMON_PATTERN_TO_HOUR);
                }
                int minute = 59;
                for (int i =  CommonConst.DIGIT_0; i <= minute; i++) {
                    String tempCode = timeCode + ":0" + i;
                    if(i>9){
                        tempCode = timeCode + ":" + i;
                    }
                    Date tempD = DateTimeUtil.toDateTime(tempCode, DateTimeUtil.COMMON_PATTERN_END_WITH_MINUTE);
                    dateList.add(tempD);
                }
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                if (!timeCode.contains(CommonConst.SINGLE_MINUS_SIGN)) {
                    timeCode = DateTimeUtil.toDateTimeStr(timeCode, DateTimeUtil.COMMON_PATTERN_DAY, DateTimeUtil.COMMON_PATTERN_TO_DAY);
zhitan-common/src/main/java/com/zhitan/common/utils/DateTimeUtil.java
@@ -10,9 +10,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.*;
/**
 * @Description: æ—¶é—´å·¥å…·ç±»
@@ -642,6 +640,35 @@
    }
    /**
     * æ ¹æ®æ—¶é—´ç±»åž‹æŠŠå­—符串转成对应的时间
     * timeType="HOUR",time="2025-02-01",返回"2025-02-01 01:00:00"
     * timeType="DAY",time="2025-02",返回"2025-02-01 01:00:00"
     * timeType="MONTH",time="2025",返回"2025-02-01 01:00:00"
     *
     * @param timeType æ—¶é—´ç±»åž‹
     * @param time     æ—¶é—´å­—符串
     * @return
     */
    public static Date getTypeTime(String timeType, String time) {
        Date dt = null;
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                dt = toDateTime(time, COMMON_PATTERN_TO_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                dt = toDateTime(time, COMMON_PATTERN_TO_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                dt = toDateTime(time, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * æ ¹æ®æ—¶é—´ç±»åž‹æŠŠè¿žç»­çš„æ—¥æœŸå­—符串转成对应的时间 ï¼ˆ202303、20230303、2023030301、202303030101)
     *
     * @param timeType æ—¶é—´ç±»åž‹
@@ -745,4 +772,148 @@
        }
        return momDate;
    }
    /**
     * é€šè¿‡æ—¶é—´ç±»åž‹è¿”回对应的时间list
     * <p>
     * å‚数:
     * timeType="YEAR",dataTime="2025-01-01 00:00:00"
     * timeType="MONTH",dataTime="2025-01-01 00:00:00"
     * timeType="DAY",dataTime="2025-01-01 00:00:00"
     * è¿”回格式:
     * [
     * {"datatime":"2025-01-01 00:00:00","value":"value1"},
     * {"datatime":"2025-02-01 00:00:00","value":"value2"},
     * {"datatime":"2025-03-01 00:00:00","value":"value3"},
     * {"datatime":"2025-04-01 00:00:00","value":"value4"},
     * {"datatime":"2025-05-01 00:00:00","value":"value5"},
     * {"datatime":"2025-06-01 00:00:00","value":"value6"},
     * {"datatime":"2025-07-01 00:00:00","value":"value7"},
     * {"datatime":"2025-08-01 00:00:00","value":"value8"},
     * {"datatime":"2025-09-01 00:00:00","value":"value9"},
     * {"datatime":"2025-10-01 00:00:00","value":"value10"},
     * {"datatime":"2025-11-01 00:00:00","value":"value11"},
     * {"datatime":"2025-12-01 00:00:00","value":"value12"}
     * ]
     *
     * @param timeType
     * @param dataTime
     * @return
     */
    public static List<TypeTime> getDateTimeList(String timeType, Date dataTime) {
        List<TypeTime> resultList = new ArrayList<>();
        Date beginTime;
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                beginTime = DateUtil.beginOfDay(dataTime);
                for (int i = 1; i <= 24; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_H + DateUtil.format(beginTime, COMMON_PATTERN_HOUR));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addHours(beginTime, 1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                beginTime = DateUtil.beginOfMonth(dataTime);
                for (int i = 1; i <= 31; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_D + DateUtil.format(beginTime, COMMON_PATTERN_DAY));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addDays(beginTime, 1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                beginTime = DateUtil.beginOfYear(dataTime);
                for (int i = 1; i <= 12; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_M + DateUtil.format(beginTime, COMMON_PATTERN_MONTH));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addMonths(beginTime, 1);
                }
                break;
        }
        return resultList;
    }
    /**
     * é€šè¿‡æ—¶é—´ç±»åž‹è¿”回对应的时间list
     * <p>
     * å‚数:
     * timeType="YEAR",dataTime="2025-01-01 00:00:00"
     * timeType="MONTH",dataTime="2025-01-01 00:00:00"
     * timeType="DAY",dataTime="2025-01-01 00:00:00"
     * è¿”回格式:
     * [
     * {"datatime":"2025-01-01 00:00:00","value":"value1"},
     * {"datatime":"2025-02-01 00:00:00","value":"value2"},
     * {"datatime":"2025-03-01 00:00:00","value":"value3"},
     * {"datatime":"2025-04-01 00:00:00","value":"value4"},
     * {"datatime":"2025-05-01 00:00:00","value":"value5"},
     * {"datatime":"2025-06-01 00:00:00","value":"value6"},
     * {"datatime":"2025-07-01 00:00:00","value":"value7"},
     * {"datatime":"2025-08-01 00:00:00","value":"value8"},
     * {"datatime":"2025-09-01 00:00:00","value":"value9"},
     * {"datatime":"2025-10-01 00:00:00","value":"value10"},
     * {"datatime":"2025-11-01 00:00:00","value":"value11"},
     * {"datatime":"2025-12-01 00:00:00","value":"value12"}
     * ]
     *
     * @param timeType
     * @param dataTime
     * @return
     */
    public static List<TypeTime> getDateTimeListSame(String timeType, Date dataTime) {
        List<TypeTime> resultList = new ArrayList<>();
        Date beginTime;
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_DAY:
                beginTime = DateUtil.beginOfDay(dataTime);
                for (int i = 1; i <= 24; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_H + DateUtil.format(beginTime, COMMON_PATTERN_HOUR));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addHours(beginTime, 1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                beginTime = DateUtil.beginOfMonth(dataTime);
                for (int i = 1; i <= 31; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_D + DateUtil.format(beginTime, COMMON_PATTERN_DAY));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addDays(beginTime, 1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                beginTime = DateUtil.beginOfYear(dataTime);
                for (int i = 1; i <= 12; i++) {
                    TypeTime typeTime = new TypeTime();
                    typeTime.setDataTime(DateUtil.format(beginTime, COMMON_PATTERN));
                    typeTime.setTimeCode(CommonConst.WORD_M + DateUtil.format(beginTime, COMMON_PATTERN_MONTH));
                    typeTime.setDateTime(beginTime);
                    typeTime.setValue("value" + i);
                    resultList.add(typeTime);
                    beginTime = addMonths(beginTime, 1);
                }
                break;
        }
        return resultList;
    }
}
zhitan-common/src/main/java/com/zhitan/common/utils/PropUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
package com.zhitan.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.zhitan.common.constant.CommonConst;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
 * @Description: å±žæ€§å€¼æ“ä½œå·¥å…·ç±»
 * @author: yxw
 * @date: 2022å¹´03月07日 9:57
 */
public class PropUtils {
    /**
     * ä¸ºå®žä½“赋值
     *
     * @param obj
     * @param propName
     * @param value
     * @return
     */
    public static Object setValue(Object obj, String propName, Object value) {
        try {
            Field field = obj.getClass().getDeclaredField(propName);
            field.setAccessible(true);
            String nameTypeName = field.getType().getTypeName();
            nameTypeName = StringUtil.ifEmptyOrNullReturnValue(nameTypeName).toLowerCase();
            if (nameTypeName.contains("float")) {
                float num = (float) DoubleUtil.toDouble(value);
                field.set(obj, num);
            } else if (nameTypeName.contains("double")) {
                field.set(obj, DoubleUtil.toDouble(value));
            } else if (nameTypeName.contains("bigdecimal")) {
                BigDecimal valueOf = BigDecimal.valueOf(Double.parseDouble(String.valueOf(value)))
                        .setScale(CommonConst.DIGIT_2, BigDecimal.ROUND_HALF_UP);
                field.set(obj, valueOf);
            } else {
                field.set(obj, value);
            }
        } catch (Exception e) {
            return null;
        }
        return obj;
    }
    /**
     * èŽ·å–å¯¹è±¡çš„æŒ‡å®šå­—æ®µçš„å€¼
     *
     * @param obj
     * @param propName
     * @return
     */
    public static String getPropValue(Object obj, String propName) {
        String propValue = "";
        try {
            if (null != obj) {
                JSONObject jsonObject = StringUtil.toJsonObject(obj);
                if (!StringUtil.isEmptyOrNull(propName)) {
                    propValue = jsonObject.getString(propName);
                }
            }
        } catch (Exception e) {
        }
        return propValue;
    }
    /**
     * èŽ·å–å¯¹è±¡çš„æŒ‡å®šå­—æ®µçš„ç±»åž‹
     * è¿”回属性的类型字符串(小写,例如:string/integer/double/date)
     *
     * @param obj      å®žä½“
     * @param propName å±žæ€§å
     * @return ï¼ˆå°å†™ï¼Œä¾‹å¦‚:string/integer/double/date)
     */
    public static String getPropType(Object obj, String propName) {
        String propType = "";
        try {
            if (null != obj && !StringUtil.isEmptyOrNull(propName)) {
                Field[] fields = obj.getClass().getDeclaredFields();
                for (Field field : fields) {
                    String name = field.getName().toLowerCase();
                    if (name.equals(propName.toLowerCase())) {
                        propType = field.getType().getSimpleName().toLowerCase();
                    }
                }
            }
        } catch (Exception e) {
        }
        return propType;
    }
    /**
     * è¡Œè½¬åˆ—
     * @param clazz ç»“果类,如 UserInfo.class
     * @param list æ•°æ®é›†
     * @return
     * @param <T>
     */
    public static  <T> List rowToColumn(Class<T> clazz, List<T> list){
        List<List> result;
        Field[] fields = clazz.getDeclaredFields();
        result = new ArrayList<>(fields.length);
        for (int i = 0; i < fields.length; i++) {
            result.add(new ArrayList());
        }
        for (T t : list) {
            for (int i = 0; i < fields.length; i++) {
                List l = result.get(i);
                Field field = fields[i];
                field.setAccessible(true);
                try {
                    l.add(field.get(t));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}
zhitan-common/src/main/java/com/zhitan/common/utils/TypeTime.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.zhitan.common.utils;
import lombok.Data;
import java.util.Date;
/**
 * [
 * {"dataTime":"2025-01-01 00:00:00","value":"value0"}
 * {"dataTime":"2025-02-01 00:00:00","value":"value1"}
 * {"dataTime":"2025-03-01 00:00:00","value":"value2"}
 * {"dataTime":"2025-04-01 00:00:00","value":"value3"}
 * {"dataTime":"2025-05-01 00:00:00","value":"value4"}
 * {"dataTime":"2025-06-01 00:00:00","value":"value5"}
 * {"dataTime":"2025-07-01 00:00:00","value":"value6"}
 * {"dataTime":"2025-08-01 00:00:00","value":"value7"}
 * {"dataTime":"2025-09-01 00:00:00","value":"value8"}
 * {"dataTime":"2025-10-01 00:00:00","value":"value9"}
 * {"dataTime":"2025-11-01 00:00:00","value":"value10"}
 * {"dataTime":"2025-12-01 00:00:00","value":"value11"}
 * }
 */
@Data
public class TypeTime {
   private String dataTime;
   private String value;
   private String timeCode;
   private Date dateTime;
}
zhitan-framework/pom.xml
@@ -5,7 +5,7 @@
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
        <version>2.5.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
zhitan-generator/.DS_Store
Binary files differ
zhitan-generator/pom.xml
@@ -5,7 +5,7 @@
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
        <version>2.5.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
zhitan-quartz/.DS_Store
Binary files differ
zhitan-quartz/pom.xml
@@ -5,7 +5,7 @@
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
        <version>2.5.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
zhitan-system/.DS_Store
Binary files differ
zhitan-system/pom.xml
@@ -5,7 +5,7 @@
    <parent>
        <artifactId>BaseAdminAPI</artifactId>
        <groupId>com.zhitan</groupId>
        <version>3.8.7</version>
        <version>2.5.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
zhitan-system/src/.DS_Store
Binary files differ
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/domain/VO/ItemizedEnergyAnalysisItemVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.zhitan.Itemizedenergyanalysis.domain.VO;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
/**
 *
 */
@Data
public class ItemizedEnergyAnalysisItemVO {
    /**
     * èŠ‚ç‚¹id
     */
    private String nodeId;
    /**
     * èŠ‚ç‚¹åç§°
     */
    private String nodeName;
    /**
     * åˆè®¡
     */
    private Double total;
    @Excel(name = "1时/1日/1月")
    private Double value0;
    @Excel(name = "2时/2日/2月")
    private Double value1;
    @Excel(name = "3时/3日/3月")
    private Double value2;
    @Excel(name = "4时/4日/4月")
    private Double value3;
    @Excel(name = "5时/5日/5月日")
    private Double value4;
    @Excel(name = "6时/6日/6月日")
    private Double value5;
    @Excel(name = "7时/7日/7月日")
    private Double value6;
    @Excel(name = "8时/8日/8月日")
    private Double value7;
    @Excel(name = "9时/9日/9月日")
    private Double value8;
    @Excel(name = "10时/10日/10月日")
    private Double value9;
    @Excel(name = "11时/11日/11月日")
    private Double value10;
    @Excel(name = "12时/12日/12月")
    private Double value11;
    @Excel(name = "13时/13日")
    private Double value12;
    @Excel(name = "14时/14日")
    private Double value13;
    @Excel(name = "15时/15日")
    private Double value14;
    @Excel(name = "16时/16日")
    private Double value15;
    @Excel(name = "17时/17日")
    private Double value16;
    @Excel(name = "18时/18日")
    private Double value17;
    @Excel(name = "19时/19日")
    private Double value18;
    @Excel(name = "20时/20日")
    private Double value19;
    @Excel(name = "21时/21日")
    private Double value20;
    @Excel(name = "22时/22日")
    private Double value21;
    @Excel(name = "23时/23日")
    private Double value22;
    @Excel(name = "24时/24日")
    private Double value23;
    @Excel(name = "25日")
    private Double value24;
    @Excel(name = "26日")
    private Double value25;
    @Excel(name = "27日")
    private Double value26;
    @Excel(name = "28日")
    private Double value27;
    @Excel(name = "29日")
    private Double value28;
    @Excel(name = "30日")
    private Double value29;
    @Excel(name = "31日")
    private Double value30;
}
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/domain/VO/ItemizedEnergyAnalysisVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.zhitan.Itemizedenergyanalysis.domain.VO;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
import java.util.List;
/**
 * åˆ†é¡¹ç”¨èƒ½åˆ†æžè¿”回类
 *
 * @author å¼ 
 */
@Data
public class ItemizedEnergyAnalysisVO {
    /**
     * åˆè®¡
     */
    private String total;
    /**
     * æœ€å¤§å€¼
     */
    private String max;
    /**
     * æœ€å°å€¼
     */
    private String min;
    /**
     * å¹³å‡å€¼
     */
    private String avg;
    /**
     * å•位
     */
    private String unit;
    private List<ItemizedEnergyAnalysisItemVO> dataList;
}
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/dto/ItemizedEnergyAnalysisDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.zhitan.Itemizedenergyanalysis.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * å‘¨æœŸæ•°æ®é¡¹.
 */
@Data
public class ItemizedEnergyAnalysisDTO {
  @ApiModelProperty(value = "时间字符串")
  private String dataTime;
  @ApiModelProperty(value = "时间类型")
  private String timeType;
  @ApiModelProperty(value = "能源类型")
  private String energyType;
  @ApiModelProperty(value = "节点Id")
  private String nodeId;
}
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/service/IItemizedEnergyAnalysisService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.zhitan.Itemizedenergyanalysis.service;
import com.zhitan.Itemizedenergyanalysis.domain.VO.ItemizedEnergyAnalysisVO;
import com.zhitan.Itemizedenergyanalysis.dto.ItemizedEnergyAnalysisDTO;
public interface IItemizedEnergyAnalysisService {
    /**
     * åˆ†é¡¹ç”¨èƒ½åˆ†æž
     * @param dto   è¯·æ±‚参数
     * @return ç»“æžœ
     */
    ItemizedEnergyAnalysisVO getItemizedEnergyAnalysisService(ItemizedEnergyAnalysisDTO dto);
}
zhitan-system/src/main/java/com/zhitan/Itemizedenergyanalysis/service/impl/ItemizedEnergyAnalysisServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,140 @@
package com.zhitan.Itemizedenergyanalysis.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zhitan.Itemizedenergyanalysis.domain.VO.ItemizedEnergyAnalysisItemVO;
import com.zhitan.Itemizedenergyanalysis.domain.VO.ItemizedEnergyAnalysisVO;
import com.zhitan.Itemizedenergyanalysis.dto.ItemizedEnergyAnalysisDTO;
import com.zhitan.Itemizedenergyanalysis.service.IItemizedEnergyAnalysisService;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.exception.ServiceException;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.PropUtils;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.dataitem.service.IDataItemService;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.realtimedata.domain.DataItem;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
 * åˆ†é¡¹ç”¨èƒ½åˆ†æž
 *
 * @author sys
 * @date 2025-03-25
 */
@Service
@AllArgsConstructor
public class ItemizedEnergyAnalysisServiceImpl implements IItemizedEnergyAnalysisService {
    @Resource
    private final ModelNodeMapper modelNodeMapper;
    @Resource
    private final IDataItemService dataItemService;
    /**
     * @param dto è¯·æ±‚参数
     * @return ç»“æžœ
     */
    @Override
    public ItemizedEnergyAnalysisVO getItemizedEnergyAnalysisService(ItemizedEnergyAnalysisDTO dto) {
        String timeType = dto.getTimeType();
        String dataTime = dto.getDataTime();
        Date beginTime = DateTimeUtil.getTime(timeType, dataTime);
        DateTime endTime = null;
        // èŽ·å–èŠ‚ç‚¹ä¿¡æ¯
        List<ModelNodeIndexInfo> nodeIndexInfo = modelNodeMapper.getModelNodeIndexIdByNodeId(dto.getNodeId(), dto.getEnergyType());
        List<String> indexList = nodeIndexInfo.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        if(ObjectUtil.isEmpty(indexList)){
            return new ItemizedEnergyAnalysisVO();
        }
        ModelNodeIndexInfo info = nodeIndexInfo.stream().findFirst().get();
        List<TypeTime> dateTimeList;
        // æ ¹æ®æ—¶é—´ç±»åž‹è°ƒæ•´æ—¶é—´èŒƒå›´
        switch (dto.getTimeType()) {
            case TimeTypeConst.TIME_TYPE_DAY:
                timeType = TimeTypeConst.TIME_TYPE_HOUR;
                endTime = DateUtil.endOfDay(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_DAY, beginTime);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                timeType = TimeTypeConst.TIME_TYPE_DAY;
                endTime = DateUtil.endOfMonth(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_MONTH, beginTime);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                timeType = TimeTypeConst.TIME_TYPE_MONTH;
                endTime = DateUtil.endOfYear(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_YEAR, beginTime);
                break;
            default:
                throw new ServiceException("时间格式错误");
        }
        // èŽ·å–æ•°æ®é¡¹åˆ—è¡¨
        List<DataItem> dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, timeType, indexList);
        // èŽ·å–æœ€å¤§å€¼ã€æœ€å°å€¼ã€åˆè®¡ã€å¹³å‡å€¼
        ItemizedEnergyAnalysisVO vo = new ItemizedEnergyAnalysisVO();
        double sum = dataItemList.stream().mapToDouble(DataItem::getValue).sum();
        double max = dataItemList.stream().mapToDouble(DataItem::getValue).max().getAsDouble();
        double min = dataItemList.stream().mapToDouble(DataItem::getValue).min().getAsDouble();
        double avg = dataItemList.stream().mapToDouble(DataItem::getValue).average().getAsDouble();
        vo.setTotal(BigDecimal.valueOf(sum).setScale(2, RoundingMode.HALF_UP).toString());
        vo.setMax(BigDecimal.valueOf(max).setScale(2, RoundingMode.HALF_UP).toString());
        vo.setMin(BigDecimal.valueOf(min).setScale(2, RoundingMode.HALF_UP).toString());
        vo.setAvg(BigDecimal.valueOf(avg).setScale(2, RoundingMode.HALF_UP).toString());
        if(ObjectUtil.isNotEmpty(info.getUnitId())){
            vo.setUnit(info.getUnitId());
        }
        List<ItemizedEnergyAnalysisItemVO> voList = new ArrayList<>();
        ItemizedEnergyAnalysisItemVO itemVO = new ItemizedEnergyAnalysisItemVO();
        itemVO.setNodeId(info.getNodeId());
        itemVO.setNodeName(info.getName());
        itemVO.setTotal(sum);
        Map<Date, List<DataItem>> dateListMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getDataTime));
        List<DataItem> results = new ArrayList<>();
        dateListMap.forEach((key, value) -> {
            DataItem dataItem = new DataItem();
            dataItem.setDataTime(key);
            //保留四位小数
            double totalValue = value.stream().map(data -> BigDecimal.valueOf(data.getValue()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(4, RoundingMode.HALF_UP).doubleValue();
            dataItem.setValue(totalValue);
            results.add(dataItem);
        });
        //根据时间排序
        results.sort(Comparator.comparing(DataItem::getDataTime));
        for (int i = 0; i < dateTimeList.size(); i++) {
            TypeTime typeTime = dateTimeList.get(i);
            Optional<DataItem> dataItem = results.stream().filter(result -> result.getDataTime().equals(typeTime.getDateTime())).findFirst();
            if (dataItem.isPresent()) {
                DataItem item = dataItem.get();
                PropUtils.setValue(itemVO, "value" + i, item.getValue());
            } else {
                PropUtils.setValue(itemVO, "value" + i, null);
            }
        }
        voList.add(itemVO);
        vo.setDataList(voList);
        return vo;
    }
}
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/AlarmAnalyisisServiceImpl.java
@@ -17,7 +17,7 @@
import com.zhitan.consumptionanalysis.domain.vo.ChartData;
import com.zhitan.consumptionanalysis.domain.vo.EnergyProportion;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.EnergyIndexMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import lombok.AllArgsConstructor;
@@ -184,8 +184,8 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,null);
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,null);
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Integer monthCount = historyAlarmMapper.selectCountByTime(beginOfMonth,endOfMonth);
        Integer yearCount = historyAlarmMapper.selectCountByTime(beginOfYear,endOfYear);
zhitan-system/src/main/java/com/zhitan/basicdata/mapper/MeterImplementMapper.java
@@ -88,4 +88,12 @@
    MeterImplement selectByNodeIdIndexId(@Param("nodeId") String nodeId, @Param("indexId") String indexId);
    List<MeterImplement> listMeterImplByInstallLocation(@Param("installactionLocation") String installactionLocation);
    /**
     * æ ¹æ®èŠ‚ç‚¹id查询计量器具信息
     *
     * @param nodeId
     * @return
     */
    List<MeterImplement> selectByNodeId(@Param("nodeId") String nodeId);
}
zhitan-system/src/main/java/com/zhitan/branchanalysis/domain/BranchAnalysisVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
package com.zhitan.branchanalysis.domain;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
@Data
public class BranchAnalysisVO {
    private String until;
    private double total;
    @Excel(name = "节点id")
    private String nodeId;
    @Excel(name = "字节名称")
    private String nodeName;
    @Excel(name = "1时/1日/1月")
    private Double value0;
    @Excel(name = "2时/2日/2月")
    private Double value1;
    @Excel(name = "3时/3日/3月")
    private Double value2;
    @Excel(name = "4时/4日/4月")
    private Double value3;
    @Excel(name = "5时/5日/5月")
    private Double value4;
    @Excel(name = "6时/6日/6月")
    private Double value5;
    @Excel(name = "7时/7日/7月")
    private Double value6;
    @Excel(name = "8时/8日/8月")
    private Double value7;
    @Excel(name = "9时/9日/9月")
    private Double value8;
    @Excel(name = "10时/10日/10月")
    private Double value9;
    @Excel(name = "11时/11日/11月")
    private Double value10;
    @Excel(name = "12时/12日/12月")
    private Double value11;
    @Excel(name = "13时/13日")
    private Double value12;
    @Excel(name = "14时/14日")
    private Double value13;
    @Excel(name = "15时/15日")
    private Double value14;
    @Excel(name = "16时/16日")
    private Double value15;
    @Excel(name = "17时/17日")
    private Double value16;
    @Excel(name = "18时18日")
    private Double value17;
    @Excel(name = "19时/19日")
    private Double value18;
    @Excel(name = "20时/20日")
    private Double value19;
    @Excel(name = "21时/21日")
    private Double value20;
    @Excel(name = "22时/22日")
    private Double value21;
    @Excel(name = "23时/23日")
    private Double value22;
    @Excel(name = "24时/24日")
    private Double value23;
    @Excel(name = "25日")
    private Double value24;
    @Excel(name = "26日")
    private Double value25;
    @Excel(name = "27日")
    private Double value26;
    @Excel(name = "28日")
    private Double value27;
    @Excel(name = "29日")
    private Double value28;
    @Excel(name = "30日")
    private Double value29;
    @Excel(name = "31日")
    private Double value30;
}
zhitan-system/src/main/java/com/zhitan/branchanalysis/mapper/BranchAnalysisMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.zhitan.branchanalysis.mapper;
import com.zhitan.branchanalysis.domain.BranchAnalysisVO;
import com.zhitan.common.utils.TypeTime;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 *支路用能分析
 *
 * @author sys
 * @date 2021-01-11
 */
public interface BranchAnalysisMapper {
    public List<BranchAnalysisVO> getBranchAnalysisList(@Param("indexIds") List<String> indexIds,
                                                        @Param("dataList") List<TypeTime> dataList,
                                                        @Param("beginTime") Date beginTime,
                                                        @Param("endTime") Date endTime,
                                                        @Param("timeType") String timeType,
                                                        @Param("indexStorageId") String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/branchanalysis/service/IBranchAnalysisService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.zhitan.branchanalysis.service;
import com.zhitan.branchanalysis.domain.BranchAnalysisVO;
import com.zhitan.realtimedata.domain.dto.BranchAnalysisDTO;
public interface IBranchAnalysisService {
    /**
     * æ”¯è·¯ç”¨èƒ½åˆ†æž
     *
     * @author sys
     * @date 2021-01-11
     */
    BranchAnalysisVO getBranchAnalysisService(BranchAnalysisDTO dataItem);
}
zhitan-system/src/main/java/com/zhitan/branchanalysis/service/impl/BranchAnalysisServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
package com.zhitan.branchanalysis.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zhitan.branchanalysis.domain.BranchAnalysisVO;
import com.zhitan.branchanalysis.service.IBranchAnalysisService;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.exception.ServiceException;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.PropUtils;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.dataitem.mapper.DataItemMapper;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.realtimedata.domain.DataItem;
import com.zhitan.realtimedata.domain.dto.BranchAnalysisDTO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
 * æ”¯è·¯ç”¨èƒ½åˆ†æž
 *
 * @author zt
 * @date 2025-03-27
 */
@Service
@AllArgsConstructor
public class BranchAnalysisServiceImpl implements IBranchAnalysisService {
    private ModelNodeMapper modelNodeMapper;
    private DataItemMapper dataItemMapper;
    @Override
    public BranchAnalysisVO getBranchAnalysisService(BranchAnalysisDTO dto) {
        String timeType = dto.getTimeType();
        String dataTime = dto.getDataTime();
        Date beginTime = DateTimeUtil.getTime(timeType, dataTime);
        DateTime endTime = null;
        List<ModelNodeIndexInfo> nodeIndexInfo = modelNodeMapper.getModelNodeIndexIdByNodeId(dto.getNodeId(), dto.getEnergyType());
        List<String> indexlist = nodeIndexInfo.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(indexlist)) {
            return new BranchAnalysisVO();
        }
        List<TypeTime> dateTimeList;
        //根据时间类型调整时间范围
        switch (dto.getTimeType()) {
            case TimeTypeConst.TIME_TYPE_DAY:
                timeType = TimeTypeConst.TIME_TYPE_HOUR;
                endTime = DateUtil.endOfDay(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_DAY, beginTime);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                timeType = TimeTypeConst.TIME_TYPE_DAY;
                endTime = DateUtil.endOfMonth(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_MONTH, beginTime);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                timeType = TimeTypeConst.TIME_TYPE_MONTH;
                endTime = DateUtil.endOfYear(beginTime);
                dateTimeList = DateTimeUtil.getDateTimeListSame(TimeTypeConst.TIME_TYPE_YEAR, beginTime);
                break;
            default:
                throw new ServiceException("时间格式错误");
        }
        BranchAnalysisVO vo = new BranchAnalysisVO();
        if (ObjectUtil.isEmpty(indexlist)) {
            return vo;
        }
        List<DataItem> dataItemlist = dataItemMapper.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, timeType, indexlist);
        double sum = dataItemlist.stream().mapToDouble(DataItem::getValue).sum();
        vo.setTotal(sum);
        vo.setNodeId(dto.getNodeId());
        vo.setNodeName(nodeIndexInfo.get(0).getName());
        Map<Date, List<DataItem>> dateListMap = dataItemlist.stream().collect(Collectors.groupingBy(DataItem::getDataTime));
        List<DataItem> results = new ArrayList<>();
        dateListMap.forEach((key, value) -> {
            DataItem dataItem = new DataItem();
            dataItem.setDataTime(key);
            //保留四位小数
            double totalValue = value.stream().map(data -> BigDecimal.valueOf(data.getValue()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(4, RoundingMode.HALF_UP).doubleValue();
            dataItem.setValue(totalValue);
            results.add(dataItem);
        });
        //根据时间排序
        results.sort(Comparator.comparing(DataItem::getDataTime));
        for (int i = 0; i < dateTimeList.size(); i++) {
            TypeTime typeTime = dateTimeList.get(i);
            Optional<DataItem> dataItem = results.stream().filter(result -> result.getDataTime().equals(typeTime.getDateTime())).findFirst();
            if (dataItem.isPresent()) {
                DataItem item = dataItem.get();
                PropUtils.setValue(vo, "value" + i, item.getValue());
            } else {
                PropUtils.setValue(vo, "value" + i, null);
            }
        }
        return vo;
    }
}
zhitan-system/src/main/java/com/zhitan/carbonemission/service/impl/CarbonEmissionServiceImpl.java
@@ -88,8 +88,8 @@
        // è®¡ç®—每种能源的当前值和去年的值
        for (String s : energyType) {
            final double value = getValues(energyMap, upCarbonEmission,energyType);
            final double lastYearValueNum = getValues(energyMap, upLastCarbonEmission,energyType);
            final double value = getValues(energyMap, upCarbonEmission, s);
            final double lastYearValueNum = getValues(energyMap, upLastCarbonEmission, s);
            allValue += value;
            allLastValue += lastYearValueNum;
            final CarbonEmissionRankVO carbonEmissionRankVO = new CarbonEmissionRankVO();
@@ -253,35 +253,61 @@
    }
    public static double getValues(Map<String, SysEnergy> energyMap, List<CarbonEmission> carbonEmissions,List<String> energyType) {
    public static double getValues(Map<String, SysEnergy> energyMap, List<CarbonEmission> carbonEmissions, List<String> energyTypeList) {
        if (CollectionUtils.isEmpty(carbonEmissions)) {
            return 0.0;
        }
        // åˆå§‹åŒ–总值
        double allValue = 0.0;
        // æŒ‰èƒ½æºID分组
        final Map<String, List<CarbonEmission>> energyValueMap = carbonEmissions.stream()
                .collect(Collectors.groupingBy(CarbonEmission::getEnergyId));
//        final List<String> energyType = sysEnergies.stream().map(SysEnergy::getEnersno).collect(Collectors.toList());
        for (String energyType : energyTypeList) {
// è®¡ç®—每种能源的当前值
        for (String s : energyType) {
            SysEnergy sysEnergy = energyMap.get(s);
            SysEnergy sysEnergy = energyMap.get(energyType);
            // ç¡®ä¿èƒ½æºå­˜åœ¨ä¸”系数不为空
            if (sysEnergy == null || sysEnergy.getCoefficient() == null) {
                throw new RuntimeException("获取碳排放转换率时出错: ç³»ç»Ÿèƒ½æºæ•°æ®ä¸­ä¸å­˜åœ¨æˆ–系数为空" + s + "能源类型");
                throw new RuntimeException("获取碳排放转换率时出错: ç³»ç»Ÿèƒ½æºæ•°æ®ä¸­ä¸å­˜åœ¨æˆ–系数为空" + energyType + "能源类型");
            }
            // èŽ·å–å¯¹åº”èƒ½æºçš„å€¼
            double value = energyValueMap.getOrDefault(s, Collections.emptyList()).stream()
            double value = energyValueMap.getOrDefault(energyType, Collections.emptyList()).stream()
                    .mapToDouble(CarbonEmission::getValue)
                    .sum();
            // ç›´æŽ¥è®¡ç®—总值,避免冗余的转换
            allValue += sysEnergy.getCoefficient().doubleValue() * value;
        }
        // æ ¼å¼åŒ–最终结果
        return Double.parseDouble(new DecimalFormat("#.00").format(allValue));
    }
    public static double getValues(Map<String, SysEnergy> energyMap, List<CarbonEmission> carbonEmissions, String energyType) {
        if (CollectionUtils.isEmpty(carbonEmissions)) {
            return 0.0;
        }
        // åˆå§‹åŒ–总值
        double allValue = 0.0;
        // æŒ‰èƒ½æºID分组
        final Map<String, List<CarbonEmission>> energyValueMap = carbonEmissions.stream()
                .collect(Collectors.groupingBy(CarbonEmission::getEnergyId));
        // è®¡ç®—每种能源的当前值
        SysEnergy sysEnergy = energyMap.get(energyType);
        // ç¡®ä¿èƒ½æºå­˜åœ¨ä¸”系数不为空
        if (sysEnergy == null || sysEnergy.getCoefficient() == null) {
            throw new RuntimeException("获取碳排放转换率时出错: ç³»ç»Ÿèƒ½æºæ•°æ®ä¸­ä¸å­˜åœ¨æˆ–系数为空" + energyType + "能源类型");
        }
        // èŽ·å–å¯¹åº”èƒ½æºçš„å€¼
        double value = energyValueMap.getOrDefault(energyType, Collections.emptyList()).stream()
                .mapToDouble(CarbonEmission::getValue)
                .sum();
        // ç›´æŽ¥è®¡ç®—总值,避免冗余的转换
        allValue += sysEnergy.getCoefficient().doubleValue() * value;
        // æ ¼å¼åŒ–最终结果
        return Double.parseDouble(new DecimalFormat("#.00").format(allValue));
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/DailyReport.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,321 @@
package com.zhitan.comprehensivestatistics.domain;
import com.zhitan.common.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 *
 * @author sys
 * @date 2020-03-25
 */
public class DailyReport implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    @Excel(name = "0时")
    private Double value0;
    @Excel(name = "1时")
    private Double value1;
    @Excel(name = "2时")
    private Double value2;
    @Excel(name = "3时")
    private Double value3;
    @Excel(name = "4时")
    private Double value4;
    @Excel(name = "5时")
    private Double value5;
    @Excel(name = "6时")
    private Double value6;
    @Excel(name = "7时")
    private Double value7;
    @Excel(name = "8时")
    private Double value8;
    @Excel(name = "9时")
    private Double value9;
    @Excel(name = "10时")
    private Double value10;
    @Excel(name = "11时")
    private Double value11;
    @Excel(name = "12时")
    private Double value12;
    @Excel(name = "13时")
    private Double value13;
    @Excel(name = "14时")
    private Double value14;
    @Excel(name = "15时")
    private Double value15;
    @Excel(name = "16时")
    private Double value16;
    @Excel(name = "17时")
    private Double value17;
    @Excel(name = "18时")
    private Double value18;
    @Excel(name = "19时")
    private Double value19;
    @Excel(name = "20时")
    private Double value20;
    @Excel(name = "21时")
    private Double value21;
    @Excel(name = "22时")
    private Double value22;
    @Excel(name = "23时")
    private Double value23;
    private List<Map> tablehead =new ArrayList<>();
    private List<DailyReport> tabledata =new ArrayList<>();
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
    public Double getValue1() {
        return value1;
    }
    public void setValue1(Double value1) {
        this.value1 = value1;
    }
    public Double getValue2() {
        return value2;
    }
    public void setValue2(Double value2) {
        this.value2 = value2;
    }
    public Double getValue3() {
        return value3;
    }
    public void setValue3(Double value3) {
        this.value3 = value3;
    }
    public Double getValue4() {
        return value4;
    }
    public void setValue4(Double value4) {
        this.value4 = value4;
    }
    public Double getValue5() {
        return value5;
    }
    public void setValue5(Double value5) {
        this.value5 = value5;
    }
    public Double getValue6() {
        return value6;
    }
    public void setValue6(Double value6) {
        this.value6 = value6;
    }
    public Double getValue7() {
        return value7;
    }
    public void setValue7(Double value7) {
        this.value7 = value7;
    }
    public Double getValue8() {
        return value8;
    }
    public void setValue8(Double value8) {
        this.value8 = value8;
    }
    public Double getValue9() {
        return value9;
    }
    public void setValue9(Double value9) {
        this.value9 = value9;
    }
    public Double getValue10() {
        return value10;
    }
    public void setValue10(Double value10) {
        this.value10 = value10;
    }
    public Double getValue11() {
        return value11;
    }
    public void setValue11(Double value11) {
        this.value11 = value11;
    }
    public Double getValue12() {
        return value12;
    }
    public void setValue12(Double value12) {
        this.value12 = value12;
    }
    public Double getValue13() {
        return value13;
    }
    public void setValue13(Double value13) {
        this.value13 = value13;
    }
    public Double getValue14() {
        return value14;
    }
    public void setValue14(Double value14) {
        this.value14 = value14;
    }
    public Double getValue15() {
        return value15;
    }
    public void setValue15(Double value15) {
        this.value15 = value15;
    }
    public Double getValue16() {
        return value16;
    }
    public void setValue16(Double value16) {
        this.value16 = value16;
    }
    public Double getValue17() {
        return value17;
    }
    public void setValue17(Double value17) {
        this.value17 = value17;
    }
    public Double getValue18() {
        return value18;
    }
    public void setValue18(Double value18) {
        this.value18 = value18;
    }
    public Double getValue19() {
        return value19;
    }
    public void setValue19(Double value19) {
        this.value19 = value19;
    }
    public Double getValue20() {
        return value20;
    }
    public void setValue20(Double value20) {
        this.value20 = value20;
    }
    public Double getValue21() {
        return value21;
    }
    public void setValue21(Double value21) {
        this.value21 = value21;
    }
    public Double getValue22() {
        return value22;
    }
    public void setValue22(Double value22) {
        this.value22 = value22;
    }
    public Double getValue23() {
        return value23;
    }
    public void setValue23(Double value23) {
        this.value23 = value23;
    }
    public Double getValue0() {
        return value0;
    }
    public void setValue0(Double value0) {
        this.value0 = value0;
    }
    public List<Map> getTablehead() {
        return tablehead;
    }
    public void setTablehead(List<Map> tablehead) {
        this.tablehead = tablehead;
    }
    public List<DailyReport> getTabledata() {
        return tabledata;
    }
    public void setTabledata(List<DailyReport> tabledata) {
        this.tabledata = tabledata;
    }
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/MonthlyComprehensive.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,415 @@
package com.zhitan.comprehensivestatistics.domain;
import com.zhitan.common.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 *
 * @author sys
 * @date 2020-12-31
 */
public class MonthlyComprehensive implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    private String unitId;
    @Excel(name = "1日")
    private Double value1;
    @Excel(name = "2日")
    private Double value2;
    @Excel(name = "3日")
    private Double value3;
    @Excel(name = "4日")
    private Double value4;
    @Excel(name = "5日")
    private Double value5;
    @Excel(name = "6日")
    private Double value6;
    @Excel(name = "7日")
    private Double value7;
    @Excel(name = "8日")
    private Double value8;
    @Excel(name = "9日")
    private Double value9;
    @Excel(name = "10日")
    private Double value10;
    @Excel(name = "11日")
    private Double value11;
    @Excel(name = "12日")
    private Double value12;
    @Excel(name = "13日")
    private Double value13;
    @Excel(name = "14日")
    private Double value14;
    @Excel(name = "15日")
    private Double value15;
    @Excel(name = "16日")
    private Double value16;
    @Excel(name = "17日")
    private Double value17;
    @Excel(name = "18日")
    private Double value18;
    @Excel(name = "19日")
    private Double value19;
    @Excel(name = "20日")
    private Double value20;
    @Excel(name = "21日")
    private Double value21;
    @Excel(name = "22日")
    private Double value22;
    @Excel(name = "23日")
    private Double value23;
    @Excel(name = "24日")
    private Double value24;
    @Excel(name = "25日")
    private Double value25;
    @Excel(name = "26日")
    private Double value26;
    @Excel(name = "27日")
    private Double value27;
    @Excel(name = "28日")
    private Double value28;
    @Excel(name = "29日")
    private Double value29;
    @Excel(name = "30日")
    private Double value30;
    @Excel(name = "31日")
    private Double value31;
    private String timeCode;
    private Integer count;
    private List<Map> tablehead =new ArrayList<>();
    private List<MonthlyComprehensive> tabledata =new ArrayList<>();
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getUnitId() {
        return unitId;
    }
    public void setUnitId(String unitId) {
        this.unitId = unitId;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
    public Double getValue1() {
        return value1;
    }
    public void setValue1(Double value1) {
        this.value1 = value1;
    }
    public Double getValue2() {
        return value2;
    }
    public void setValue2(Double value2) {
        this.value2 = value2;
    }
    public Double getValue3() {
        return value3;
    }
    public void setValue3(Double value3) {
        this.value3 = value3;
    }
    public Double getValue4() {
        return value4;
    }
    public void setValue4(Double value4) {
        this.value4 = value4;
    }
    public Double getValue5() {
        return value5;
    }
    public void setValue5(Double value5) {
        this.value5 = value5;
    }
    public Double getValue6() {
        return value6;
    }
    public void setValue6(Double value6) {
        this.value6 = value6;
    }
    public Double getValue7() {
        return value7;
    }
    public void setValue7(Double value7) {
        this.value7 = value7;
    }
    public Double getValue8() {
        return value8;
    }
    public void setValue8(Double value8) {
        this.value8 = value8;
    }
    public Double getValue9() {
        return value9;
    }
    public void setValue9(Double value9) {
        this.value9 = value9;
    }
    public Double getValue10() {
        return value10;
    }
    public void setValue10(Double value10) {
        this.value10 = value10;
    }
    public Double getValue11() {
        return value11;
    }
    public void setValue11(Double value11) {
        this.value11 = value11;
    }
    public Double getValue12() {
        return value12;
    }
    public void setValue12(Double value12) {
        this.value12 = value12;
    }
    public Double getValue13() {
        return value13;
    }
    public void setValue13(Double value13) {
        this.value13 = value13;
    }
    public Double getValue14() {
        return value14;
    }
    public void setValue14(Double value14) {
        this.value14 = value14;
    }
    public Double getValue15() {
        return value15;
    }
    public void setValue15(Double value15) {
        this.value15 = value15;
    }
    public Double getValue16() {
        return value16;
    }
    public void setValue16(Double value16) {
        this.value16 = value16;
    }
    public Double getValue17() {
        return value17;
    }
    public void setValue17(Double value17) {
        this.value17 = value17;
    }
    public Double getValue18() {
        return value18;
    }
    public void setValue18(Double value18) {
        this.value18 = value18;
    }
    public Double getValue19() {
        return value19;
    }
    public void setValue19(Double value19) {
        this.value19 = value19;
    }
    public Double getValue20() {
        return value20;
    }
    public void setValue20(Double value20) {
        this.value20 = value20;
    }
    public Double getValue21() {
        return value21;
    }
    public void setValue21(Double value21) {
        this.value21 = value21;
    }
    public Double getValue22() {
        return value22;
    }
    public void setValue22(Double value22) {
        this.value22 = value22;
    }
    public Double getValue23() {
        return value23;
    }
    public void setValue23(Double value23) {
        this.value23 = value23;
    }
    public Double getValue24() {
        return value24;
    }
    public void setValue24(Double value24) {
        this.value24 = value24;
    }
    public Double getValue25() {
        return value25;
    }
    public void setValue25(Double value25) {
        this.value25 = value25;
    }
    public Double getValue26() {
        return value26;
    }
    public void setValue26(Double value26) {
        this.value26 = value26;
    }
    public Double getValue27() {
        return value27;
    }
    public void setValue27(Double value27) {
        this.value27 = value27;
    }
    public Double getValue28() {
        return value28;
    }
    public void setValue28(Double value28) {
        this.value28 = value28;
    }
    public Double getValue29() {
        return value29;
    }
    public void setValue29(Double value29) {
        this.value29 = value29;
    }
    public Double getValue30() {
        return value30;
    }
    public void setValue30(Double value30) {
        this.value30 = value30;
    }
    public Double getValue31() {
        return value31;
    }
    public void setValue31(Double value31) {
        this.value31 = value31;
    }
    public List<Map> getTablehead() {
        return tablehead;
    }
    public void setTablehead(List<Map> tablehead) {
        this.tablehead = tablehead;
    }
    public List<MonthlyComprehensive> getTabledata() {
        return tabledata;
    }
    public void setTabledata(List<MonthlyComprehensive> tabledata) {
        this.tabledata = tabledata;
    }
    public String getTimeCode() {
        return timeCode;
    }
    public void setTimeCode(String timeCode) {
        this.timeCode = timeCode;
    }
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/domain/YearComperhensive.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,214 @@
package com.zhitan.comprehensivestatistics.domain;
import com.zhitan.common.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 *
 * @author sys
 * @date 2020-03-25
 */
public class YearComperhensive implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    private String unitId;
    @Excel(name = "1月")
    private Double value1;
    @Excel(name = "2月")
    private Double value2;
    @Excel(name = "3月")
    private Double value3;
    @Excel(name = "4月")
    private Double value4;
    @Excel(name = "5月")
    private Double value5;
    @Excel(name = "6月")
    private Double value6;
    @Excel(name = "7月")
    private Double value7;
    @Excel(name = "8月")
    private Double value8;
    @Excel(name = "9月")
    private Double value9;
    @Excel(name = "10月")
    private Double value10;
    @Excel(name = "11月")
    private Double value11;
    @Excel(name = "12月")
    private Double value12;
    private String timeCode;
    private List<Map> tablehead =new ArrayList<>();
    private List<DailyReport> tabledata =new ArrayList<>();
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getUnitId() {
        return unitId;
    }
    public void setUnitId(String unitId) {
        this.unitId = unitId;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
    public Double getValue1() {
        return value1;
    }
    public void setValue1(Double value1) {
        this.value1 = value1;
    }
    public Double getValue2() {
        return value2;
    }
    public void setValue2(Double value2) {
        this.value2 = value2;
    }
    public Double getValue3() {
        return value3;
    }
    public void setValue3(Double value3) {
        this.value3 = value3;
    }
    public Double getValue4() {
        return value4;
    }
    public void setValue4(Double value4) {
        this.value4 = value4;
    }
    public Double getValue5() {
        return value5;
    }
    public void setValue5(Double value5) {
        this.value5 = value5;
    }
    public Double getValue6() {
        return value6;
    }
    public void setValue6(Double value6) {
        this.value6 = value6;
    }
    public Double getValue7() {
        return value7;
    }
    public void setValue7(Double value7) {
        this.value7 = value7;
    }
    public Double getValue8() {
        return value8;
    }
    public void setValue8(Double value8) {
        this.value8 = value8;
    }
    public Double getValue9() {
        return value9;
    }
    public void setValue9(Double value9) {
        this.value9 = value9;
    }
    public Double getValue10() {
        return value10;
    }
    public void setValue10(Double value10) {
        this.value10 = value10;
    }
    public Double getValue11() {
        return value11;
    }
    public void setValue11(Double value11) {
        this.value11 = value11;
    }
    public Double getValue12() {
        return value12;
    }
    public void setValue12(Double value12) {
        this.value12 = value12;
    }
    public String getTimeCode() {
        return timeCode;
    }
    public void setTimeCode(String timeCode) {
        this.timeCode = timeCode;
    }
    public List<Map> getTablehead() {
        return tablehead;
    }
    public void setTablehead(List<Map> tablehead) {
        this.tablehead = tablehead;
    }
    public List<DailyReport> getTabledata() {
        return tabledata;
    }
    public void setTabledata(List<DailyReport> tabledata) {
        this.tabledata = tabledata;
    }
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/DailyComprehensiveMapper.java
@@ -1,6 +1,5 @@
package com.zhitan.comprehensivestatistics.mapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.DailyComprehensive;
import org.apache.ibatis.annotations.Param;
@@ -18,13 +17,13 @@
                                                              @Param("dataList") List<DailyComprehensive> dataList,
                                                              @Param("beginTime") Date beginTime,
                                                              @Param("endTime") Date endTime,
                                                              @Param("timeType") TimeType timeType,
                                                              @Param("timeType") String timeType,
                                                              @Param("indexStorageId") String indexStorageId);
    List<DailyComprehensive> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") TimeType timeType,
                                            @Param("timeType") String timeType,
                                            @Param("indexStorageId")  String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/MonthlyComprehensiveMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.zhitan.comprehensivestatistics.mapper;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ æœˆ
 *
 * @author sys
 * @date 2020-03-25
 */
public interface MonthlyComprehensiveMapper {
    /**
     * èŽ·å–ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆæœˆï¼‰åˆ—è¡¨
     *
     * @param nodeId
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    public List<MonthlyComprehensive> getMonthlyComprehensiveList(@Param("nodeId") String nodeId,
                                                                  @Param("dataList") List<MonthlyComprehensive> dataList,
                                                                  @Param("beginTime") Date beginTime,
                                                                  @Param("endTime") Date endTime,
                                                                  @Param("timeType") String timeType,
                                                                  @Param("indexStorageId") String indexStorageId);
    /**
     * èŽ·å–ç»¼åˆæŒ‡æ ‡åˆ†æžå›¾è¡¨ï¼ˆæœˆï¼‰æ•°æ®
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<MonthlyComprehensive> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") String timeType,
                                            @Param("indexStorageId") String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/YearComprehensiveMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.zhitan.comprehensivestatistics.mapper;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ å¹´
 *
 * @author sys
 * @date 2020-03-25
 */
public interface YearComprehensiveMapper {
    /**
     * èŽ·å–å¹´æ•°æ®
     *
     * @param nodeId
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    public List<YearComperhensive> getYearComprehensiveList(@Param("nodeId") String nodeId,
                                                            @Param("dataList") List<YearComperhensive> dataList,
                                                            @Param("beginTime") Date beginTime,
                                                            @Param("endTime") Date endTime,
                                                            @Param("timeType") String timeType,
                                                            @Param("indexStorageId") String indexStorageId);
    /**
     * èŽ·å–å¹´æ•°æ®-chart
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<YearComperhensive> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") String timeType,
                                            @Param("indexStorageId") String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IDailyComprehensiveService.java
@@ -1,7 +1,6 @@
package com.zhitan.comprehensivestatistics.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.DailyComprehensive;
import java.util.Date;
@@ -14,6 +13,6 @@
 * @date 2020-03-25
 */
public interface IDailyComprehensiveService {
    public List<DailyComprehensive> getDailyComprehensiveList(String nodeId, List<DailyComprehensive> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<DailyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    public List<DailyComprehensive> getDailyComprehensiveList(String nodeId, List<DailyComprehensive> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    List<DailyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/ImonthlyComprehensive.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.zhitan.comprehensivestatistics.service;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import java.util.Date;
import java.util.List;
/**
 * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ æœˆ
 *
 * @author sys
 * @date 2020-03-25
 */
public interface ImonthlyComprehensive {
    /**
     * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ æœˆ
     *
     * @param nodeId
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<MonthlyComprehensive> getMonthlyComprehensiveList(String nodeId, List<MonthlyComprehensive> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ æœˆ
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<MonthlyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IyearComprehensive.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.zhitan.comprehensivestatistics.service;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import java.util.Date;
import java.util.List;
/**
 * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ å¹´
 *
 * @author sys
 * @date 2020-03-25
 */
public interface IyearComprehensive {
    /**
     * èŽ·å–ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆå¹´ï¼‰åˆ—è¡¨
     *
     * @param nodeId
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<YearComperhensive> getYearComprehensiveList(String nodeId, List<YearComperhensive> dataList,
                                                            Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     * èŽ·å–ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆå¹´ï¼‰å›¾è¡¨æ•°æ®
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<YearComperhensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/DailyComprehensiveServiceImpl.java
@@ -1,6 +1,5 @@
package com.zhitan.comprehensivestatistics.service.impl;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.DailyComprehensive;
import com.zhitan.comprehensivestatistics.mapper.DailyComprehensiveMapper;
import com.zhitan.comprehensivestatistics.service.IDailyComprehensiveService;
@@ -24,7 +23,7 @@
    private DailyComprehensiveMapper dailyMapper;
    public List<DailyComprehensive> getDailyComprehensiveList(String nodeId, List<DailyComprehensive> dataList,
                                                              Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
                                                              Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (StringUtils.isNotEmpty(nodeId)) {
            return dailyMapper.getDailyComprehensiveList(nodeId, dataList, beginTime, endTime, timeType, indexStorageId);
@@ -32,7 +31,7 @@
        return Collections.emptyList();
    }
    @Override
    public List<DailyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<DailyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return dailyMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/MonthlyComprehensiveServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.zhitan.comprehensivestatistics.service.impl;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import com.zhitan.comprehensivestatistics.mapper.MonthlyComprehensiveMapper;
import com.zhitan.comprehensivestatistics.service.ImonthlyComprehensive;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
 * ä¸šåŠ¡å±‚å¤„ç†
 *
 * @author sys
 * @date 2020-03-25
 */
@Service
public class MonthlyComprehensiveServiceImpl implements ImonthlyComprehensive {
    @Resource
    private MonthlyComprehensiveMapper monthMapper;
    public List<MonthlyComprehensive> getMonthlyComprehensiveList(String nodeId, List<MonthlyComprehensive> dataList,
                                                                  Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (StringUtils.isNotEmpty(nodeId)) {
            return monthMapper.getMonthlyComprehensiveList(nodeId, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<MonthlyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return monthMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
        return Collections.emptyList();
    }
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/YearComprehensiveServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.zhitan.comprehensivestatistics.service.impl;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import com.zhitan.comprehensivestatistics.mapper.YearComprehensiveMapper;
import com.zhitan.comprehensivestatistics.service.IyearComprehensive;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * ä¸šåŠ¡å±‚å¤„ç†
 *
 * @author sys
 * @date 2020-03-25
 */
@Service
public class YearComprehensiveServiceImpl implements IyearComprehensive {
    @Resource
    private YearComprehensiveMapper yearMapper;
    @Override
    public List<YearComperhensive> getYearComprehensiveList(String nodeId, List<YearComperhensive> dataList,
                                                            Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (StringUtils.isNotEmpty(nodeId)) {
            return yearMapper.getYearComprehensiveList(nodeId, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<YearComperhensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        List<YearComperhensive> dataList = new ArrayList<>();
        if (StringUtils.isNotEmpty(indexId)) {
            List<YearComperhensive> listChart = yearMapper.getListChart(indexId, beginTime, endTime, timeType, indexStorageId);
            if (CollectionUtils.isNotEmpty(listChart)) {
                Date date = new Date();
                YearComperhensive first = listChart.get(CommonConst.DIGIT_0);
                Map<String, YearComperhensive> listChartMap = yearMapper.getListChart(indexId, beginTime, endTime, timeType, indexStorageId)
                        .stream().collect(Collectors.toMap(YearComperhensive::getTimeCode, prot -> prot));
                while (beginTime.before(date)) {
                    YearComperhensive yearComperhensive = new YearComperhensive();
                    String format = CommonConst.WORD_M + DateUtil.format(beginTime, DateTimeUtil.COMMON_PATTERN_MONTH);
                    YearComperhensive item = listChartMap.get(format);
                    if (ObjectUtils.isNotEmpty(item)) {
                        yearComperhensive = item;
                    } else {
                        yearComperhensive.setTimeCode(format);
                        yearComperhensive.setIndexId(indexId);
                        yearComperhensive.setTimeType(timeType);
                        yearComperhensive.setUnitId(first.getUnitId());
                        yearComperhensive.setIndexName(first.getIndexName());
                    }
                    dataList.add(yearComperhensive);
                    beginTime = DateUtil.offsetMonth(beginTime, CommonConst.DIGIT_1);
                }
            }
        }
        return dataList;
    }
}
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/domain/vo/RankingEnergyData.java
@@ -1,12 +1,14 @@
package com.zhitan.consumptionanalysis.domain.vo;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Data
public class RankingEnergyData {
    public String nodeId;
    public String nodeName;
    public String energyTypeNo;
    public String energyTypeName;
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/service/impl/ConsumptionAnalysisServiceImpl.java
@@ -15,7 +15,7 @@
import com.zhitan.dataitem.service.IDataItemService;
import com.zhitan.energyIndicators.domain.EnergyIndicators;
import com.zhitan.energyIndicators.mapper.EnergyIndicatorsMapper;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.productoutput.domain.ProductOutput;
@@ -67,12 +67,12 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
//        }
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime;
        Date endTime;
        Date lastTime;
@@ -258,9 +258,9 @@
        final String parentId = dto.getNodeId();
        //根据总结点查询
        final List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(parentId);
        final List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(parentId);
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -275,12 +275,12 @@
        });
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        // æ ¹æ®nodeId获取能源类型
        // æ‰€æœ‰ç‚¹ä½ä¿¡æ¯
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).distinct().collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).distinct().collect(Collectors.toList());
        Date beginTime;
        Date endTime;
@@ -362,11 +362,11 @@
     * @param nodeId
     * @return
     */
    private List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInfor(String nodeId) {
        List<ModelNodeIndexInfor> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
    private List<ModelNodeIndexInfo> listModelNodeIndexIdRelationInfor(String nodeId) {
        List<ModelNodeIndexInfo> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
        // å¦‚果是空存在两种情况,1:id有问题,2:最底层
        if (CollectionUtils.isEmpty(nodeInforList)) {
            List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
            List<ModelNodeIndexInfo> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
            if (CollectionUtils.isNotEmpty(inforList)) {
                nodeInforList.addAll(inforList);
            }
@@ -391,14 +391,14 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
//        }
        //修改过滤统计点位
        nodeIndexInforList = nodeIndexInforList.stream().filter(x -> "STATISTIC".equals(x.getIndexType())).collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -412,7 +412,7 @@
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime;
        Date endTime;
        Date lastTime;
@@ -714,13 +714,13 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
//        }
        nodeIndexInforList = nodeIndexInforList.stream().filter(x -> "STATISTIC".equals(x.getIndexType())).collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -733,7 +733,7 @@
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime;
        Date endTime;
        String queryTimeType = dto.getTimeType();
@@ -838,7 +838,7 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(nodeId);
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(nodeId);
        final Map<String, String> nodeNameMap = new HashMap<>();
        nodeIndexInforList.forEach(n -> {
            final String id = n.getNodeId();
@@ -848,9 +848,9 @@
            }
        });
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -865,7 +865,7 @@
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime;
        Date endTime;
        String queryTimeType = dto.getTimeType();
@@ -895,7 +895,7 @@
        Map<String, BigDecimal> resultMap = new HashMap<>();
        nodeIndexMap.forEach((key, value) -> {
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
            indexIdList.forEach(indexId -> {
                final List<DataItem> dataItems = dataItemMap.get(indexId);
@@ -994,9 +994,9 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -1009,7 +1009,7 @@
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime;
        Date endTime;
        String queryTimeType = dto.getTimeType();
zhitan-system/src/main/java/com/zhitan/costmanagement/service/impl/DeviationAnalysisServiceServiceImpl.java
@@ -11,7 +11,7 @@
import com.zhitan.costmanagement.mapper.CostPriceRelevancyMapper;
import com.zhitan.costmanagement.service.DeviationAnalysisService;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelInfoMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.peakvalley.domain.ElectricityDataItem;
@@ -123,9 +123,9 @@
        }else{
            out.setNodeId(nodeId);
            List<StatisticsInfoListOut> child = new ArrayList<>();
            List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
                List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet, dto.getTimeType());
                StatisticsDataOutItem nowData = compute(dto.getTimeType(),dto.getDate(),nodeId,dataItemList);
                BeanUtil.copyProperties(nowData,out);
@@ -169,9 +169,9 @@
        for(ModelNode modelNode:modelNodeList){
            StatisticsInfoListOut out = new StatisticsInfoListOut();
            String nodeId = modelNode.getNodeId();
            List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
                List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet, dto.getTimeType());
                StatisticsDataOutItem nowData = compute(dto.getTimeType(),dto.getDate(),nodeId,dataItemList);
                BeanUtil.copyProperties(nowData,out);
@@ -209,11 +209,11 @@
        List<String>xData2 = new ArrayList<>();
        List<BigDecimal>yData = new ArrayList<>();
        Map<String, Object>result = new HashMap<>();
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            String dateStr = dto.getDate();
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = new ArrayList<>();
@@ -260,9 +260,9 @@
        StatisticsDataOutItem result = new StatisticsDataOutItem();
//        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet, dto.getTimeType());
            StatisticsDataOutItem nowData = compute(dto.getTimeType(),dto.getDate(),dto.getNodeId(),dataItemList);
            BeanUtil.copyProperties(nowData,result);
@@ -399,9 +399,9 @@
    private StatisticsInfoListOut computeInfoList(DeviationAnalysisDTO dto,List<String>nodes,List<ModelNode>modelNodeList,String nodeId){
        StatisticsInfoListOut out = new StatisticsInfoListOut();
        List<StatisticsInfoListOut> child = new ArrayList<>();
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet, dto.getTimeType());
            StatisticsDataOutItem nowData = compute(dto.getTimeType(),dto.getDate(),nodeId,dataItemList);
            BeanUtil.copyProperties(nowData,out);
@@ -432,9 +432,9 @@
                    StatisticsInfoListOut out2 = new StatisticsInfoListOut();
                    out2.setNodeId(node);
                    List<ModelNodeIndexInfor> nodeIndexInfoList2 = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), node);
                    List<ModelNodeIndexInfo> nodeIndexInfoList2 = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), node);
                    if (CollectionUtils.isNotEmpty(nodeIndexInfoList2)) {
                        Set<String> indexSet2 = nodeIndexInfoList2.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
                        Set<String> indexSet2 = nodeIndexInfoList2.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
                        List<ElectricityDataItem> dataItemList2 = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet2, dto.getTimeType());
                        StatisticsDataOutItem nowData2 = compute(dto.getTimeType(),dto.getDate(),node,dataItemList2);
                        BeanUtil.copyProperties(nowData2,out2);
@@ -516,9 +516,9 @@
        }else{
            out.setNodeId(nodeId);
            List<StatisticsInfoListOut> child = new ArrayList<>();
            List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), nodeId);
            if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
                Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
                List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatisticsDeviationAnalysis(indexSet, dto.getTimeType());
                StatisticsDataOutItem nowData = compute(dto.getTimeType(),dto.getDate(),nodeId,dataItemList);
                BeanUtil.copyProperties(nowData,out);
zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhitan.carbonemission.domain.CarbonEmission;
import com.zhitan.common.enums.TimeType;
import com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData;
import com.zhitan.dataitem.domain.StagseDataEntry;
import com.zhitan.realtimedata.domain.DataItem;
import org.apache.ibatis.annotations.Param;
@@ -80,6 +81,7 @@
    /**
     * æ ¹æ®indexId与时间范围查询碳排放数据,上半部分
     *
     * @param beginTime
     * @param endTime
     * @param timeType
@@ -92,6 +94,7 @@
    /**
     * æ ¹æ®indexId与时间范围查询碳排放数据,中间部分
     *
     * @param beginTime
     * @param endTime
     * @param timeType
@@ -103,6 +106,7 @@
    /**
     * æ ¹æ®indexId与时间范围查询碳排放数据,下半部分
     *
     * @param beginTime
     * @param endTime
     * @param timeType
@@ -123,4 +127,31 @@
     */
    List<DataItem> getDataItemHourInforByIndexIds(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                                  @Param("timeType") String timeType, @Param("indexIds") List<String> indexIds);
    /**
     * æŸ¥è¯¢èƒ½æºç±»åž‹éžç”µçš„用量
     *
     * @param beginTime
     * @param endTime
     * @param timeType   æ—¶é—´ç±»åž‹
     * @param nodeId     èŠ‚ç‚¹Id
     * @param energyType èƒ½æºç±»åž‹
     * @return
     */
    BigDecimal getDataItemTimeRangeValueByNodeId(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                                 @Param("timeType") String timeType, @Param("nodeId") String nodeId, @Param("energyType") String energyType);
    /**
     * èƒ½æºæ¶ˆè€—排名
     *
     * @param nodeIds
     * @param timeType
     * @param beginTime
     * @param endTime
     * @return
     */
    List<RankingEnergyData> getHomePageConsumptionRanking(@Param("nodeIds") List<String> nodeIds,
                                                          @Param("timeType") String timeType,
                                                          @Param("beginTime") Date beginTime,
                                                          @Param("endTime") Date endTime);
}
zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java
@@ -2,6 +2,7 @@
import com.zhitan.common.enums.TimeType;
import com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData;
import com.zhitan.dataitem.domain.StagseDataEntry;
import com.zhitan.realtimedata.domain.DataItem;
import com.zhitan.statisticalAnalysis.domain.dto.FlowChartsDTO;
@@ -98,4 +99,14 @@
     * @return ç»“æžœ
     */
    FlowChartsVO getFlowCharts(FlowChartsDTO dto);
    /**
     * èŽ·å–é¦–é¡µèƒ½è€—æŽ’å
     * @param nodeIds
     * @param timeType
     * @param beginTime
     * @param endTime
     * @return
     */
    List<RankingEnergyData> getHomePageConsumptionRanking(List<String> nodeIds, String timeType, Date beginTime, Date endTime);
}
zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java
@@ -1,6 +1,9 @@
package com.zhitan.dataitem.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhitan.common.enums.TimeType;
import com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData;
import com.zhitan.dataitem.domain.StagseDataEntry;
import com.zhitan.dataitem.domain.vo.NodeIndexValueVO;
import com.zhitan.dataitem.mapper.DataItemMapper;
@@ -149,16 +152,20 @@
    public FlowChartsVO getFlowCharts(FlowChartsDTO dto) {
        FlowChartsVO flowChartsVO = new FlowChartsVO();
        // çˆ¶èŠ‚ç‚¹id
        String nodeId = dto.getNodeId();
        LambdaQueryWrapper<ModelNode> wrapper = Wrappers.<ModelNode>lambdaQuery()
                .eq(ModelNode::getModelCode, dto.getModelCode())
                .isNull(ModelNode::getParentId);
        List<ModelNode> modelNodes = modelNodeMapper.selectList(wrapper);
        if (ObjectUtils.isEmpty(modelNodes)) {
            throw new RuntimeException("未查询到模型信息");
        }
        ModelNode modelNode = modelNodes.stream().findFirst().get();
        String nodeId = modelNode.getNodeId();
        dto.setNodeId(nodeId);
        String energyType = dto.getEnergyType();
        LocalDate queryTime = dto.getQueryTime();
        TimeType timeType = dto.getTimeType();
        // èŽ·å–èŠ‚ç‚¹ä¿¡æ¯
        ModelNode modelNode = modelNodeMapper.selectModelNodeById(nodeId);
        if (ObjectUtils.isEmpty(modelNode)) {
            return flowChartsVO;
        }
        // èŽ·å–æŸ¥è¯¢æ—¶é—´
        Map<String, LocalDateTime> dateTimeMap = getDataItemByIndexId(timeType, queryTime);
@@ -207,6 +214,11 @@
        return flowChartsVO;
    }
    @Override
    public List<RankingEnergyData> getHomePageConsumptionRanking(List<String> nodeIds, String timeType, Date beginTime, Date endTime) {
        return dataItemMapper.getHomePageConsumptionRanking(nodeIds, timeType, beginTime, endTime);
    }
    /**
     * æ ¹æ®indexId查询能耗数据
     */
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/IElectricLoadService.java
@@ -1,7 +1,10 @@
package com.zhitan.energyMonitor.service;
import com.zhitan.energyMonitor.domain.vo.ListElectricLoadVO;
import com.zhitan.energyMonitor.domain.vo.ListElectricityMeterVO;
import com.zhitan.model.domain.EnergyIndex;
import java.util.List;
/**
 * @Description:
@@ -14,5 +17,12 @@
    /**
     * èŽ·å–è´Ÿè·åˆ†æžæ•°æ®
     */
    ListElectricLoadVO list(String timeType, String timeCode, EnergyIndex energyIndex);
    ListElectricLoadVO list(String timeType, String timeCode, EnergyIndex energyIndex, String meterId);
    /**
     * èŽ·å–èŠ‚ç‚¹ä¸‹æ‰€æœ‰ç”µè¡¨
     * @param nodeId
     * @return
     */
    List<ListElectricityMeterVO> listElectricMeter(String nodeId);
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/ElectricLoadServiceImpl.java
@@ -14,7 +14,9 @@
import com.zhitan.energyMonitor.domain.vo.ListElectricLoadDetail;
import com.zhitan.energyMonitor.domain.vo.ListElectricLoadItem;
import com.zhitan.energyMonitor.domain.vo.ListElectricLoadVO;
import com.zhitan.energyMonitor.domain.vo.ListElectricityMeterVO;
import com.zhitan.energyMonitor.service.IElectricLoadService;
import com.zhitan.knowledgeBase.domain.enums.EnergyTypeEnum;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
@@ -28,6 +30,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @Description: sensor_alarm_item
@@ -43,7 +46,7 @@
    private MeterImplementMapper meterImplementMapper;
    @Override
    public ListElectricLoadVO list(String timeType, String timeCode, EnergyIndex energyIndex) {
    public ListElectricLoadVO list(String timeType, String timeCode, EnergyIndex energyIndex, String meterId) {
        ListElectricLoadVO vo = new ListElectricLoadVO();
        List<ListElectricLoadItem> itemList = new ArrayList<>();
        vo.setItemList(itemList);
@@ -56,7 +59,7 @@
        detail.setRate(CommonConst.DOUBLE_MINUS_SIGN);
        vo.setDetail(detail);
        MeterImplement meterImplement = meterImplementMapper.selectById(energyIndex.getMeterId());
        MeterImplement meterImplement = meterImplementMapper.selectById(meterId);
        if (ObjectUtil.isEmpty(meterImplement)) {
            return vo;
@@ -124,6 +127,7 @@
        List<TagValue> minList = new ArrayList<>();
        List<TagValue> avgList = new ArrayList<>();
        if (TimeTypeConst.TIME_TYPE_DAY.equals(timeType)) {
        } else {
            String tempTimeCode = StringUtil.ifEmptyOrNullReturnValue(timeCode).replace(CommonConst.SINGLE_MINUS_SIGN, CommonConst.EMPTY);
            Date start = DateTimeUtil.toDateTime(tempTimeCode, DateTimeUtil.COMMON_PATTERN_MONTH);
@@ -230,13 +234,13 @@
                TagValue rt3 = realtimeDatabaseService.statistics(code, date, endTime, CollectionModes.max);
                TagValue rt4 = realtimeDatabaseService.statistics(code, date, endTime, CollectionModes.min);
                TagValue rt2 = realtimeDatabaseService.statistics(code, date, endTime, CollectionModes.mean);
                if (ObjectUtils.isNotEmpty(rt2.getValue())) {
                if (ObjectUtils.isNotEmpty(rt2)) {
                    temp.setAvg(String.valueOf(DoubleUtil.formatDouble(rt2.getValue())));
                }
                if (ObjectUtils.isNotEmpty(rt3.getValue())) {
                if (ObjectUtils.isNotEmpty(rt3)) {
                    temp.setMax(String.valueOf(DoubleUtil.formatDouble(rt3.getValue())));
                }
                if (ObjectUtils.isNotEmpty(rt4.getValue())) {
                if (ObjectUtils.isNotEmpty(rt4)) {
                    temp.setMin(String.valueOf(DoubleUtil.formatDouble(rt4.getValue())));
                }
            }
@@ -255,4 +259,20 @@
    }
    /**
     * èŽ·å–ç”µè¡¨åˆ—è¡¨
     */
    @Override
    public List<ListElectricityMeterVO> listElectricMeter(String nodeId) {
        List<MeterImplement> meterImplements = meterImplementMapper.selectByNodeId(nodeId);
        meterImplements = meterImplements.stream().filter(x -> "electric".equals(x.getEnergyType())).collect(Collectors.toList());
        List<ListElectricityMeterVO> list = new ArrayList<>();
        for (MeterImplement meterImplement : meterImplements) {
            ListElectricityMeterVO vo = new ListElectricityMeterVO();
            vo.setCode(meterImplement.getId());
            vo.setLabel(meterImplement.getMeterName());
            list.add(vo);
        }
        return list;
    }
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/ElectricThreePhaseServiceImpl.java
@@ -54,9 +54,7 @@
    @Override
    public ElectricThreePhaseVO list(String timeType, String timeCode, List<EnergyIndex> energyIndexList, String requestType, String meterId) {
        ElectricThreePhaseVO vo = new ElectricThreePhaseVO();
        if (ObjectUtil.isEmpty(energyIndexList)) {
            return vo;
        }
        // èŽ·å–ç”µåŽ‹ä¸å¹³è¡¡æ•°æ®
        if (CommonConst.STR_NUMBER_0.equals(requestType)) {
            energyIndexList = energyIndexList.stream()
@@ -70,9 +68,13 @@
                            || StringUtil.ifEmptyOrNullReturnValue(x.getCode()).trim().endsWith(CommonConst.TAG_CODE_CURRENT_C))
                    .collect(Collectors.toList());
        }
        if (ObjectUtil.isEmpty(energyIndexList)) {
            return vo;
        }
        List<String> tagCodeList = energyIndexList.stream().map(EnergyIndex::getCode).collect(Collectors.toList());
        if(ObjectUtil.isEmpty(tagCodeList)){
        tagCodeList.add(CommonConst.STR_NUMBER_MINUS_ONE);
        String tagCodes = String.join(StrUtil.COMMA, tagCodeList);
        }
        Date start = ChartUtils.getDateTime(timeType, timeCode);
        Date end = getEndTime(timeType, start);
@@ -82,7 +84,7 @@
        long millis = new Duration(begin, finish).getMillis();
        int pointCount = IntegerUtil.toInt(millis / CommonConst.DIGIT_3600 / CommonConst.DIGIT_1000);
        List<TagValue> tagValueList = realtimeDatabaseService.retrieve(tagCodes, start, end, pointCount);
        List<TagValue> tagValueList = realtimeDatabaseService.retrieve(tagCodeList, start, end, pointCount);
        List<ElectricThreePhaseItem> itemList = new ArrayList<>();
        List<Date> dateList = new ArrayList<>();
        ChartUtils.generateDateList(timeType, timeCode, dateList);
@@ -281,10 +283,14 @@
     */
    private void listDayData(Date date, List<TagValue> tagValueList, ElectricThreePhaseItem temp, ElectricThreePhaseTempModel tempModel) {
        Date endTime = DateTimeUtil.addHours(date, CommonConst.DIGIT_1);
        List<TagValue> currentTagValueList = tagValueList.stream().filter(x -> DateTimeUtil.compareDateDiff(date, x.getDataTime()) <= 0 && DateTimeUtil.compareDateDiff(endTime, x.getDataTime()) > 0).collect(Collectors.toList());
        List<TagValue> currentATagValueList = currentTagValueList.stream().filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith("_A")).collect(Collectors.toList());
        List<TagValue> currentBTagValueList = currentTagValueList.stream().filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith("_B")).collect(Collectors.toList());
        List<TagValue> currentCTagValueList = currentTagValueList.stream().filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith("_C")).collect(Collectors.toList());
        List<TagValue> currentTagValueList = tagValueList.stream()
                .filter(x -> DateTimeUtil.compareDateDiff(date, x.getDataTime()) <= 0 && DateTimeUtil.compareDateDiff(endTime, x.getDataTime()) > 0).collect(Collectors.toList());
        List<TagValue> currentATagValueList = currentTagValueList.stream()
                .filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith(CommonConst.A_PHASE)).collect(Collectors.toList());
        List<TagValue> currentBTagValueList = currentTagValueList.stream()
                .filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith(CommonConst.B_PHASE)).collect(Collectors.toList());
        List<TagValue> currentCTagValueList = currentTagValueList.stream()
                .filter(x -> StringUtil.ifEmptyOrNullReturnValue(x.getTagCode()).trim().endsWith(CommonConst.C_PHASE)).collect(Collectors.toList());
        TagValue tagValueA = currentATagValueList.stream().filter(x -> DateTimeUtil.compareDateDiff(date, x.getDataTime()) == 0).findAny().orElse(null);
        TagValue tagValueB = currentBTagValueList.stream().filter(x -> DateTimeUtil.compareDateDiff(date, x.getDataTime()) == 0).findAny().orElse(null);
        TagValue tagValueC = currentCTagValueList.stream().filter(x -> DateTimeUtil.compareDateDiff(date, x.getDataTime()) == 0).findAny().orElse(null);
zhitan-system/src/main/java/com/zhitan/energydata/mapper/EnergyDataStatisticMapper.java
@@ -1,7 +1,6 @@
package com.zhitan.energydata.mapper;
import com.zhitan.model.domain.CalcFunction;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -9,5 +8,5 @@
public interface EnergyDataStatisticMapper
{
    List<ModelNodeIndexInfor> getModelNodeIndexIdByFixedNodeIds(@Param("modelCode")String modelCode,@Param("fixedNodeIds") List<String> fixedNodeIds);
    List<ModelNodeIndexInfo> getModelNodeIndexIdByFixedNodeIds(@Param("modelCode")String modelCode, @Param("fixedNodeIds") List<String> fixedNodeIds);
}
zhitan-system/src/main/java/com/zhitan/energydata/service/impl/EnergyDataStatisticServiceImpl.java
@@ -27,7 +27,7 @@
import com.zhitan.home.domain.vo.HomeEnergyStatisticsVO;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.EnergyIndexMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.service.IEnergyIndexService;
@@ -37,10 +37,10 @@
import com.zhitan.peakvalley.domain.vo.peakvalley.*;
import com.zhitan.peakvalley.mapper.PeakValleyMapper;
import com.zhitan.realtimedata.domain.DataItem;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@@ -52,37 +52,24 @@
import java.util.stream.Collectors;
/**
 * æ’邦综合治理大屏接口实现类
 * ç»¼åˆæ²»ç†å¤§å±æŽ¥å£å®žçŽ°ç±»
 */
@Service
@AllArgsConstructor
public class EnergyDataStatisticServiceImpl implements IEnergyDataStatisticService {
  @Autowired
  private ModelNodeMapper modelNodeMapper;
  @Autowired
  private PeakValleyMapper electricityDataItemMapper;
  @Autowired
  CostPriceRelevancyMapper costPriceRelevancyMapper;
  @Autowired
  CostElectricityInputMapper electricityInputMapper;
  @Autowired
  private  IDataItemService dataItemService;
  @Autowired
  private SysEnergyMapper sysEnergyMapper;
  @Autowired
  private  IModelNodeService modelNodeService;
  @Autowired
  private  IEnergyIndexService energyIndexService;
  @Autowired
  private EnergyDataStatisticMapper statisticMapper;
  @Autowired
  private EnergyIndexMapper energyIndexMapper;
  @Autowired
  private MeterImplementMapper meterImplementMapper;
  @Override
@@ -157,9 +144,9 @@
    Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
    // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
    List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
      List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
      electricityDataMap = dataItemList.stream()
@@ -335,9 +322,9 @@
    Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
    // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
    List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
      List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
      electricityDataMap = dataItemList.stream()
@@ -537,9 +524,9 @@
    Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
    // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
    List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
    if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
      List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
      electricityDataMap = dataItemList.stream()
@@ -677,7 +664,7 @@
      return energyDataList;
    }
    final List<String> nodeIds = modelNodeList.stream().map(ModelNode::getNodeId).collect(Collectors.toList());
    List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.selectIndexByNodeIds(modelCode ,nodeIds);
    List<ModelNodeIndexInfo> nodeIndexInforList = modelNodeMapper.selectIndexByNodeIds(modelCode ,nodeIds);
    final Map<String, String> nodeNameMap = new HashMap<>();
    nodeIndexInforList.forEach(n->{
@@ -689,9 +676,9 @@
    });
    // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
    Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
            Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
    final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
    Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeIndexInforList.stream().collect(
            Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
    final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
    final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
    final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
@@ -706,7 +693,7 @@
        indexIdEnergyIdMap.put(indexId,energyId);
      }
    });
    List<String> indexIds = nodeIndexInforList.stream().filter(l -> StringUtils.isNotEmpty(l.getIndexId())).map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
    List<String> indexIds = nodeIndexInforList.stream().filter(l -> StringUtils.isNotEmpty(l.getIndexId())).map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
    Date queryTime = new Date();
    Date beginTime;
    Date endTime;
@@ -736,7 +723,7 @@
    Map<String,BigDecimal> resultMap = new HashMap<>();
    nodeIndexMap.forEach((key, value) -> {
      // æ‰¾å‡ºindexIds
      List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).filter(Objects::nonNull).collect(Collectors.toList());
      List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).filter(Objects::nonNull).collect(Collectors.toList());
      if (null!=indexIdList &&!indexIdList.isEmpty()){
        indexIdList.forEach(indexId -> {
          final List<DataItem> dataItems = dataItemMap.get(indexId);
@@ -903,9 +890,9 @@
    Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
// æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
    List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(modelCode, nodeId);
    List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(modelCode, nodeId);
    if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
      Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
      List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime,endTime , timeType);
      electricityDataMap = dataItemList.stream()
@@ -988,7 +975,7 @@
    fixedNodeIds.add("dca20897-5977-40ae-a28a-88a6acdee335");//冶三
    fixedNodeIds.add("4912c751-0611-4f4b-afce-0f58629512b7");//精炼
    fixedNodeIds.add("8eef471f-880c-4636-a428-620a4d2ccd5d");//矿业
    fixedNodeIds.add("6d6a0412-7c6d-4654-9cb3-0079655e23e5");//恒邦新材料
    fixedNodeIds.add("6d6a0412-7c6d-4654-9cb3-0079655e23e5");//新材料
    LambdaQueryWrapper<ModelNode> nodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
    nodeLambdaQueryWrapper.eq(ModelNode::getModelCode,modelCode);
@@ -1002,14 +989,14 @@
    Map<String,ModelNode> nodeMap=nodeList.stream().collect(Collectors.toMap(ModelNode::getNodeId,x->x));
    List<ModelNodeIndexInfor> indexList=statisticMapper.getModelNodeIndexIdByFixedNodeIds(modelCode,fixedNodeIds);
    List<ModelNodeIndexInfo> indexList=statisticMapper.getModelNodeIndexIdByFixedNodeIds(modelCode,fixedNodeIds);
    // æ ¹æ®åŽ‚åŒºåˆ†ç»„
    Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = indexList.stream().collect(
            Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
    Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = indexList.stream().collect(
            Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
    //查询所有能源类型
    final List<String> eneryIdList = indexList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
    final List<String> eneryIdList = indexList.stream().map(ModelNodeIndexInfo::getEnergyId).distinct().collect(Collectors.toList());
    final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
@@ -1022,7 +1009,7 @@
        indexIdEnergyIdMap.put(indexId,energyId);
      }
    });
    List<String> indexIds = indexList.stream().filter(l -> StringUtils.isNotEmpty(l.getIndexId())).map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
    List<String> indexIds = indexList.stream().filter(l -> StringUtils.isNotEmpty(l.getIndexId())).map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
//        Date queryTime = new Date();
    Date queryTime = new Date();
    Date beginTime;
@@ -1072,18 +1059,18 @@
      }
      //node和index关联集合
      List<ModelNodeIndexInfor> value=nodeIndexMap.get(key);
      List<ModelNodeIndexInfo> value=nodeIndexMap.get(key);
      List<HomeEnergyStatisticsVO> itemVo=new ArrayList<>();
      //根据能源类型分组
      Map<String, List<ModelNodeIndexInfor>> sysEnergyIds = value.stream().collect(
              Collectors.groupingBy(ModelNodeIndexInfor::getEnergyId));
      Map<String, List<ModelNodeIndexInfo>> sysEnergyIds = value.stream().collect(
              Collectors.groupingBy(ModelNodeIndexInfo::getEnergyId));
      if (!sysEnergyIds.isEmpty()) {
        //遍历
        for (Map.Entry<String, List<ModelNodeIndexInfor>> entry : sysEnergyIds.entrySet()) {
        for (Map.Entry<String, List<ModelNodeIndexInfo>> entry : sysEnergyIds.entrySet()) {
          String energyIndex = entry.getKey();
          List<ModelNodeIndexInfor> energyValue = entry.getValue();
          List<ModelNodeIndexInfo> energyValue = entry.getValue();
          if (energyCoefficientMap.containsKey(energyIndex)) {
            SysEnergy sysEnergy = energyCoefficientMap.get(energyIndex);
            HomeEnergyStatisticsVO item = new HomeEnergyStatisticsVO();
@@ -1095,7 +1082,7 @@
            BigDecimal totalConsumption = BigDecimal.ZERO;
            BigDecimal totalCount = BigDecimal.ZERO;
            //合计值
            for (ModelNodeIndexInfor valueItem:entry.getValue()){
            for (ModelNodeIndexInfo valueItem:entry.getValue()){
              List<DataItem> dataItems = dataItemMap.get(valueItem.getIndexId());
              if (CollectionUtils.isNotEmpty(dataItems)) {
                BigDecimal sum = BigDecimal.valueOf(dataItems.stream()
@@ -1171,8 +1158,8 @@
    if (ObjectUtils.isEmpty(modelNode)) {
      return voList;
    }
    List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
    List<String> indexIds = inforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
    List<ModelNodeIndexInfo> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
    List<String> indexIds = inforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
    // é€šè¿‡indexIds找data_Item数据
    List<DataItem> itemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
    // æŸ¥è¯¢ç‚¹ä½è¯¦ç»†ä¿¡æ¯
zhitan-system/src/main/java/com/zhitan/home/service/HomePageServiceImpl.java
@@ -5,7 +5,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhitan.basicdata.domain.SysEnergy;
import com.zhitan.basicdata.mapper.SysEnergyMapper;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.core.domain.entity.SysDictData;
import com.zhitan.common.enums.TimeType;
import com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData;
@@ -16,7 +15,7 @@
import com.zhitan.home.service.impl.IHomePageService;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.service.IEnergyIndexService;
import com.zhitan.model.service.IModelNodeService;
@@ -30,9 +29,7 @@
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -48,18 +45,11 @@
public class HomePageServiceImpl implements IHomePageService {
    private final SysEnergyMapper sysEnergyMapper;
    private final IModelNodeService modelNodeService;
    private final IDataItemService dataItemService;
    private final IEnergyIndexService energyIndexService;
    private final ISysDictDataService sysDictDataService;
    @Resource
    private ModelNodeMapper modelNodeMapper;
    @Resource
    private PeakValleyMapper electricityDataItemMapper;
@@ -141,8 +131,8 @@
        if (ObjectUtils.isEmpty(modelNode)) {
            return voList;
        }
        List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
        List<String> indexIds = inforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<ModelNodeIndexInfo> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
        List<String> indexIds = inforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        // é€šè¿‡indexIds找data_Item数据
        List<DataItem> itemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        // æŸ¥è¯¢ç‚¹ä½è¯¦ç»†ä¿¡æ¯
@@ -220,9 +210,9 @@
        double totalElectric;
        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(modelcode, firstModeNodeInfo.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(modelcode, firstModeNodeInfo.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, beginTime, endTime, shixuTimeType);
            if(null != dataItemList){
                totalElectric = dataItemList.stream().map(ElectricityDataItem::getElectricity).mapToDouble(BigDecimal::doubleValue).sum();
@@ -257,12 +247,8 @@
        List<String> xdataList = new ArrayList<>();
        // æŸ¥è¯¢æ‰€æœ‰èƒ½æºç±»åž‹
        List<SysEnergy> sysEnergies = sysEnergyMapper.selectSysEnergyList(new SysEnergy());
        final Map<String, Object> energyCollectMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        final Map<String, String> energyNameMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getEnername));
        Date queryTime = new Date();
//        Date queryTime = DateUtil.parseDateTime("2023-03-28 00:00:00");
        Date beginTime;
        Date endTime;
        String shixuTimeType;
@@ -292,8 +278,8 @@
        if (ObjectUtils.isEmpty(modelNode)) {
            return vo;
        }
        List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
        List<String> indexIds = inforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<ModelNodeIndexInfo> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelNode.getNodeId());
        List<String> indexIds = inforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        // é€šè¿‡indexIds找data_Item数据
        List<DataItem> itemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        final Map<String, List<DataItem>> dataItemMap = itemList.stream().collect(Collectors.groupingBy(li -> DateUtil.format(li.getDataTime(), timeFormat)));
@@ -304,22 +290,30 @@
                .filter(l -> StringUtils.isNotEmpty(l.getEnergyId())).collect(Collectors.groupingBy(
                        EnergyIndex::getEnergyId, Collectors.mapping(EnergyIndex::getIndexId, Collectors.toList())
                ));
        List<String> lengList = new ArrayList<>();
        while (!beginTime.after(endTime)) {
            final String currentTime = DateUtil.format(beginTime, timeFormat);
            xdataList.add(currentTime);
            final List<DataItem> dataItems = dataItemMap.get(currentTime);
            List<Double> energyCount = new ArrayList<>();
            energyTypeMap.forEach((energyType,IndexIdList)->{
            sysEnergies.forEach(x -> {
                if(!lengList.contains(x.getEnername())){
                    lengList.add(x.getEnername());
                }
                List<String> indexIdList = energyTypeMap.get(x.getEnersno());
                double sum;
                if(null == dataItems){
                if (null == dataItems || CollectionUtils.isEmpty(indexIdList)) {
                    sum = 0;
                }else {
                    sum = dataItems.stream().filter(li -> IndexIdList.contains(li.getIndexId())).mapToDouble(DataItem::getValue).sum();
                    sum = dataItems.stream().filter(li -> indexIdList.contains(li.getIndexId())).mapToDouble(DataItem::getValue).sum();
                }
                final BigDecimal coefficient = (BigDecimal) energyCollectMap.get(energyType);
                energyCount.add(sum * coefficient.doubleValue());
                energyCount.add(sum * x.getCoefficient().doubleValue());
            });
            ydataList.add(energyCount);
            switch (TimeType.valueOf(timeType)) {
                case DAY:
                    beginTime = DateUtil.offsetHour(beginTime, 1);
@@ -334,11 +328,6 @@
        }
        vo.setXdata(xdataList.toArray(new String[0]));
        Double[][] array = new Double[sysEnergies.size()][xdataList.size()];
        List<String> lengList = new ArrayList<>();
        energyCollectMap.keySet().forEach(key->{
            final String name = energyNameMap.get(key);
            lengList.add(name);
        });
        for(int i = 0; i < ydataList.size(); i++){
            final List<Double> doubleList = ydataList.get(i);
@@ -352,108 +341,51 @@
    }
    @Override
    public List<RankingEnergyData> energyConsumptionRanking(String modelcode, String timeType) {
    public List<RankingEnergyData> energyConsumptionRanking(String modelCode, String timeType) {
        List<RankingEnergyData> energyDataList = new ArrayList<>();
        String nodeCategory = "2";
        LambdaQueryWrapper<ModelNode> modelNodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        modelNodeLambdaQueryWrapper.eq(ModelNode::getModelCode,modelcode);
        modelNodeLambdaQueryWrapper.eq(ModelNode::getNodeCategory,nodeCategory);
        List<ModelNode> modelNodeList = modelNodeMapper.selectList(modelNodeLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(modelNodeList)){
            return energyDataList;
        }
        final List<String> nodeIds = modelNodeList.stream().map(ModelNode::getNodeId).collect(Collectors.toList());
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.selectIndexByNodeIds(modelcode ,nodeIds);
        final Map<String, String> nodeNameMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
            final String id = n.getNodeId();
            final String name = n.getName();
            if(!nodeNameMap.containsKey(id)){
                nodeNameMap.put(id,name);
            }
        });
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        //能源编号和能源折标系数
        final Map<String, Object> energyCoefficientMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        //index和能源
        final Map<String, String> indexIdEnergyIdMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
            final String indexId = n.getIndexId();
            final String energyId = n.getEnergyId();
            if(!indexIdEnergyIdMap.containsKey(indexId)){
                indexIdEnergyIdMap.put(indexId,energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().filter(l -> StringUtils.isNotEmpty(l.getIndexId())).map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        Date queryTime = new Date();
//        Date queryTime = DateUtil.parseDateTime("2023-03-28 00:00:00");
        Date beginTime;
        Date endTime;
        String shixuTimeType;
        if (TimeType.DAY.name().equals(timeType)) {
            beginTime = DateUtil.beginOfDay(queryTime);
            endTime = DateUtil.endOfDay(queryTime);
            shixuTimeType = TimeType.HOUR.name();
            timeType = TimeType.HOUR.name();
            // æœˆ
        } else if (TimeType.MONTH.name().equals(timeType)) {
            beginTime = DateUtil.beginOfMonth(queryTime);
            endTime = DateUtil.endOfMonth(queryTime);
            shixuTimeType = TimeType.DAY.name();
            timeType = TimeType.DAY.name();
            // å¹´
        } else {
        } else if (TimeType.YEAR.name().equals(timeType)) {
            beginTime = DateUtil.beginOfYear(queryTime);
            endTime = DateUtil.endOfYear(queryTime);
            shixuTimeType = TimeType.MONTH.name();
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        }
        Map<String, List<DataItem>> dataItemMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getIndexId));
            timeType = TimeType.MONTH.name();
        Map<String,BigDecimal> resultMap = new HashMap<>();
        nodeIndexMap.forEach((key, value) -> {
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            indexIdList.forEach(indexId->{
                final List<DataItem> dataItems = dataItemMap.get(indexId);
                final String energyId = indexIdEnergyIdMap.get(indexId);
                final BigDecimal coefficient = (BigDecimal) energyCoefficientMap.get(energyId);
                if(CollectionUtils.isNotEmpty(dataItems) ){
                    BigDecimal sum = BigDecimal.valueOf(dataItems.stream()
                            .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(coefficient);
                    if (resultMap.containsKey(key)) {
                        resultMap.put(key, resultMap.get(key).add(sum));
                    } else {
                        resultMap.put(key, sum);
            return energyDataList;
                    }
        LambdaQueryWrapper<ModelNode> parentNodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        parentNodeLambdaQueryWrapper.eq(ModelNode::getModelCode, modelCode);
        List<ModelNode> modelNodeList = modelNodeMapper.selectList(parentNodeLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(modelNodeList)) {
            return energyDataList;
                }
        ModelNode parentNode = modelNodeList.stream().filter(x -> ObjectUtils.isEmpty(x.getParentId())).findFirst().orElse(null);
        if (ObjectUtils.isEmpty(parentNode)) {
            return energyDataList;
        }
        List<String> nodeIds = modelNodeList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getParentId()) && parentNode.getNodeId().equals(x.getParentId()))
                .map(ModelNode::getNodeId).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(nodeIds)) {
            return energyDataList;
        }
        energyDataList = dataItemService.getHomePageConsumptionRanking(nodeIds, timeType, beginTime, endTime);
        energyDataList.forEach(x -> {
            x.energyConsumption = new BigDecimal(x.energyConsumption).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            });
        });
        resultMap.forEach((key,value)->{
            RankingEnergyData rankingEnergyData = new RankingEnergyData();
            rankingEnergyData.setNodeId(key);
            rankingEnergyData.setNodeName(nodeNameMap.get(key));
            rankingEnergyData.setEnergyConsumption(value.doubleValue());
            energyDataList.add(rankingEnergyData);
        });
        Collections.sort(energyDataList, Comparator.comparingDouble((RankingEnergyData item) -> item.getEnergyConsumption()).reversed());
        // èŽ·å–å‰5条记录
        List<RankingEnergyData> top5Items = energyDataList.subList(0, Math.min(5, energyDataList.size()));
        return top5Items;
        return energyDataList;
    }
}
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/DailyKeyEquipmentMapper.java
@@ -1,7 +1,6 @@
package com.zhitan.keyequipment.mapper;
import com.zhitan.basicdata.domain.FacilityArchives;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.DailyKeyEquipment;
import org.apache.ibatis.annotations.Param;
@@ -19,12 +18,12 @@
                                                            @Param("dataList") List<DailyKeyEquipment> dataList,
                                                            @Param("beginTime") Date beginTime,
                                                            @Param("endTime") Date endTime,
                                                            @Param("timeType") TimeType timeType,
                                                            @Param("timeType") String timeType,
                                                            @Param("indexStorageId") String indexStorageId);
    List<DailyKeyEquipment> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") TimeType timeType,
                                            @Param("timeType") String timeType,
                                            @Param("indexStorageId")  String indexStorageId);
    List<FacilityArchives> getFacilityArchives();
    List<FacilityArchives> getPointFacility();
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/MonthlyKeyEquipmentMapper.java
@@ -1,6 +1,5 @@
package com.zhitan.keyequipment.mapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.MonthlyKeyEquipment;
import org.apache.ibatis.annotations.Param;
@@ -18,12 +17,12 @@
                                                                @Param("dataList") List<MonthlyKeyEquipment> dataList,
                                                                @Param("beginTime") Date beginTime,
                                                                @Param("endTime") Date endTime,
                                                                @Param("timeType") TimeType timeType,
                                                                @Param("timeType") String timeType,
                                                                @Param("indexStorageId") String indexStorageId);
    List<MonthlyKeyEquipment> getListChart(@Param("indexId") String indexId,
                                               @Param("beginTime") Date beginTime,
                                               @Param("endTime") Date endTime,
                                               @Param("timeType") TimeType timeType,
                                               @Param("timeType") String timeType,
                                               @Param("indexStorageId") String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/keyequipment/mapper/YearKeyEquipmentMapper.java
@@ -1,6 +1,6 @@
package com.zhitan.keyequipment.mapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.keyequipment.domain.YearKeyEquipment;
import org.apache.ibatis.annotations.Param;
@@ -15,15 +15,15 @@
 */
public interface YearKeyEquipmentMapper {
    public List<YearKeyEquipment> getYearKeyEquipmentList(@Param("indexIds") List<String> indexIds,
                                                          @Param("dataList") List<YearKeyEquipment> dataList,
                                                          @Param("dataList") List<TypeTime> dataList,
                                                          @Param("beginTime") Date beginTime,
                                                          @Param("endTime") Date endTime,
                                                          @Param("timeType") TimeType timeType,
                                                          @Param("timeType") String timeType,
                                                          @Param("indexStorageId") String indexStorageId);
    List<YearKeyEquipment> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") TimeType timeType,
                                            @Param("indexStorageId") String indexStorageId);
                                            @Param("timeType") String timeType
                                            );
}
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IDailyKeyEquipmentService.java
@@ -1,7 +1,6 @@
package com.zhitan.keyequipment.service;
import com.zhitan.basicdata.domain.FacilityArchives;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.DailyKeyEquipment;
import java.util.Date;
@@ -14,8 +13,8 @@
 * @date 2021-01-11
 */
public interface IDailyKeyEquipmentService {
    public List<DailyKeyEquipment> getdailyKeyEquipmentList(List<String> indexIds, List<DailyKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    public List<DailyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    public List<DailyKeyEquipment> getdailyKeyEquipmentList(List<String> indexIds, List<DailyKeyEquipment> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    public List<DailyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
    public List<FacilityArchives> getFacilityArchives();
    public List<FacilityArchives> getPointFacility();
}
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IMonthlyKeyEquipmentService.java
@@ -1,7 +1,6 @@
package com.zhitan.keyequipment.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.MonthlyKeyEquipment;
import java.util.Date;
@@ -14,6 +13,8 @@
 * @date 2021-01-11
 */
public interface IMonthlyKeyEquipmentService {
    public List<MonthlyKeyEquipment> getMonthlyKeyEquipmentList(List<String> indexIds, List<MonthlyKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<MonthlyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<MonthlyKeyEquipment> getMonthlyKeyEquipmentList(List<String> indexIds, List<MonthlyKeyEquipment> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    List<MonthlyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/keyequipment/service/IYearKeyEquipmentService.java
@@ -1,8 +1,9 @@
package com.zhitan.keyequipment.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.keyequipment.domain.YearKeyEquipment;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import java.util.Date;
import java.util.List;
@@ -14,6 +15,7 @@
 * @date 2021-01-11
 */
public interface IYearKeyEquipmentService {
    public List<YearKeyEquipment> getYearKeyEquipmentList(List<String> indexIds, List<YearKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<YearKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<YearKeyEquipment> getYearKeyEquipmentList(List<String> indexIds, List<TypeTime> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    List<YearKeyEquipment> getListChart(DataItemQueryDTO queryDto);
}
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/DailyKeyEquipmentServiceImpl.java
@@ -1,7 +1,6 @@
package com.zhitan.keyequipment.service.impl;
import com.zhitan.basicdata.domain.FacilityArchives;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.DailyKeyEquipment;
import com.zhitan.keyequipment.mapper.DailyKeyEquipmentMapper;
import com.zhitan.keyequipment.service.IDailyKeyEquipmentService;
@@ -23,15 +22,25 @@
    @Autowired
    private DailyKeyEquipmentMapper dailyKeyEquipmentMapper;
    /**
     *
     * @param indexIds
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    @Override
    public List<DailyKeyEquipment> getdailyKeyEquipmentList(List<String> indexIds, List<DailyKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<DailyKeyEquipment> getdailyKeyEquipmentList(List<String> indexIds, List<DailyKeyEquipment> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()) {
            return dailyKeyEquipmentMapper.getdailyKeyEquipmentList(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<DailyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<DailyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return dailyKeyEquipmentMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/MonthlyKeyEquipmentServiceImpl.java
@@ -1,6 +1,5 @@
package com.zhitan.keyequipment.service.impl;
import com.zhitan.common.enums.TimeType;
import com.zhitan.keyequipment.domain.MonthlyKeyEquipment;
import com.zhitan.keyequipment.mapper.MonthlyKeyEquipmentMapper;
import com.zhitan.keyequipment.service.IMonthlyKeyEquipmentService;
@@ -23,7 +22,7 @@
    private MonthlyKeyEquipmentMapper monthlyKeyEquipmentMapper;
    @Override
    public List<MonthlyKeyEquipment> getMonthlyKeyEquipmentList(List<String> indexIds, List<MonthlyKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<MonthlyKeyEquipment> getMonthlyKeyEquipmentList(List<String> indexIds, List<MonthlyKeyEquipment> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()) {
            return monthlyKeyEquipmentMapper.getMonthlyKeyEquipmentList(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
@@ -31,7 +30,7 @@
    }
    @Override
    public List<MonthlyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<MonthlyKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return monthlyKeyEquipmentMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
zhitan-system/src/main/java/com/zhitan/keyequipment/service/impl/YearKeyEquipmentServiceImpl.java
@@ -1,9 +1,14 @@
package com.zhitan.keyequipment.service.impl;
import com.zhitan.common.enums.TimeType;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.keyequipment.domain.YearKeyEquipment;
import com.zhitan.keyequipment.mapper.YearKeyEquipmentMapper;
import com.zhitan.keyequipment.service.IYearKeyEquipmentService;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -22,17 +27,19 @@
    @Autowired
    private YearKeyEquipmentMapper yearKeyEquipmentMapper;
    public List<YearKeyEquipment> getYearKeyEquipmentList(List<String> indexIds, List<YearKeyEquipment> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    public List<YearKeyEquipment> getYearKeyEquipmentList(List<String> indexIds, List<TypeTime> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()) {
            return yearKeyEquipmentMapper.getYearKeyEquipmentList(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<YearKeyEquipment> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return yearKeyEquipmentMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
        return Collections.emptyList();
    public List<YearKeyEquipment> getListChart(DataItemQueryDTO queryDto){
        if(ObjectUtils.isEmpty(queryDto.getIndexId())){
            return Collections.emptyList();}
        Date convertTime = DateTimeUtil.getTime(queryDto.getTimeType(), queryDto.getDataTime());
        DateTime beginTime = DateUtil.beginOfYear(convertTime);
        DateTime endTime = DateUtil.endOfYear(convertTime);
        return yearKeyEquipmentMapper.getListChart(queryDto.getIndexId(),beginTime,endTime,queryDto.getTimeType());
    }
}
zhitan-system/src/main/java/com/zhitan/model/domain/DaqTemplate.java
@@ -25,6 +25,8 @@
  @Excel(name = "参数编码")
  private String code;
  @Excel(name = "采集编码")
  private String gatewayKey;
  /**
   * å‚数名称
   */
@@ -90,4 +92,12 @@
  public void setUnit(String unit) {
    this.unit = unit;
  }
  public String getGatewayKey() {
    return gatewayKey;
  }
  public void setGatewayKey(String gatewayKey) {
    this.gatewayKey = gatewayKey;
  }
}
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.zhitan.model.domain.vo;
import com.zhitan.common.core.domain.BaseEntity;
import lombok.Data;
/**
 * æ¨¡åž‹èŠ‚ç‚¹ä¸Žç‚¹ä½å…³ç³»å¯¹è±¡
 *
 * @Author: Zhujw
 * @Date: 2023/3/2
 */
@Data
public class ModelNodeIndexInfo extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * æ¨¡åž‹åç§°
     */
    private String modelName;
    /**
     * æ¨¡åž‹ç¼–码
     */
    private String modelCode;
    /**
     * èŠ‚ç‚¹id
     */
    private String nodeId;
    /**
     * èŠ‚ç‚¹åç§°
     */
    private String name;
    /**
     * èŠ‚ç‚¹ç¼–ç 
     */
    private String nodeCode;
    /**
     * åç§°
     */
    private String nodeName;
    /**
     * ç‚¹ä½id
     */
    private String indexId;
    /**
     * ç‚¹ä½åç§°
     */
    private String indexName;
    /**
     * ç‚¹ä½ç¼–码
     */
    private String indexCode;
    /**
     * èƒ½æºç±»åž‹
     */
    private String energyId;
    /**
     * ç‚¹ä½ç±»åž‹
     */
    private String indexType;
    /**
     * å•位
     */
    private String unitId;
}
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfor.java
@@ -2,6 +2,7 @@
import com.zhitan.common.core.domain.BaseEntity;
import lombok.Data;
/**
 * æ¨¡åž‹èŠ‚ç‚¹ä¸Žç‚¹ä½å…³ç³»å¯¹è±¡
@@ -9,6 +10,7 @@
 * @Author: Zhujw
 * @Date: 2023/3/2
 */
@Data
public class ModelNodeIndexInfor extends BaseEntity {
  private static final long serialVersionUID = 1L;
@@ -33,44 +35,8 @@
  private String energyId;
  private String indexType;
  public String getNodeId() {
    return nodeId;
  }
  public void setNodeId(String nodeId) {
    this.nodeId = nodeId;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getIndexId() {
    return indexId;
  }
  public void setIndexId(String indexId) {
    this.indexId = indexId;
  }
  public String getEnergyId() {
    return energyId;
  }
  public void setEnergyId(String energyId) {
    this.energyId = energyId;
  }
  public String getIndexType() {
    return indexType;
  }
  public void setIndexType(String indexType) {
    this.indexType = indexType;
  }
  /**
   * å•位
   */
  private String unitId;
}
zhitan-system/src/main/java/com/zhitan/model/mapper/DaqTemplateMapper.java
@@ -65,6 +65,9 @@
    int dapHasExistWhenUpdate(@Param("id") String id, @Param("code") String code, @Param("deviceType") String deviceType);
    int dapCodeHasExist(@Param("kay") String key, @Param("deviceType") String deviceType);
    int dapCodeHasExistWhenUpdate(@Param("id") String id, @Param("key") String code, @Param("deviceType") String deviceType);
    /**
     * æŸ¥è¯¢æŒ‡æ ‡æ¨¡æ¿ä¿¡æ¯
     *
zhitan-system/src/main/java/com/zhitan/model/mapper/EnergyIndexMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.EnergyIndexQuery;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -89,7 +90,7 @@
  List<EnergyIndex> selectEnergyIndex(EnergyIndexQuery query);
  void removeNodeIndex(@Param("nodeId")String nodeId, @Param("indexIds")List<String> indexIds);
  void removeEnergyIndex(@Param("indexIds")List<String> indexIds);
  void saveEnergyIndex(List<EnergyIndex> insertData);
@@ -100,4 +101,8 @@
  Page<EnergyIndex> selectEnergyIndexPage(@Param("page")Page<?> page, @Param("query") EnergyIndexQuery energyIndexQuery);
    List<EnergyIndex> getIndexByCode(@Param("code")String code, @Param("nodeId")String nodeId);
  List<EnergyIndex> getIndexByMeterIdIndexCode(@Param("meterId") String meterId, @Param("indexCode") String indexCode, @Param("nodeId") String nodeId);
  List<ModelNodeIndexInfo> getModelNodeIndexInfoListByIndexIds(@Param("indexIds") String[] indexIds);
}
zhitan-system/src/main/java/com/zhitan/model/mapper/ModelNodeMapper.java
@@ -9,7 +9,7 @@
import com.zhitan.dataitem.domain.vo.NodeIndexValueVO;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
@@ -138,7 +138,7 @@
     * @param code
     * @return
     */
    List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByCode(@Param("code") String code);
    List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByCode(@Param("code") String code);
    /**
     * æ ¹æ®nodeId查询对应详细信息
@@ -146,7 +146,7 @@
     * @param nodeId
     * @return
     */
    List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByNodeId(@Param("nodeId") String nodeId);
    List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByNodeId(@Param("nodeId") String nodeId);
    /**
     * æ ¹æ®çˆ¶id查询详细信息
@@ -154,7 +154,7 @@
     * @param parentId
     * @return
     */
    List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInforByParentId(@Param("parentId") String parentId);
    List<ModelNodeIndexInfo> listModelNodeIndexIdRelationInforByParentId(@Param("parentId") String parentId);
    /**
     * æ ¹æ®code查询父级信息
@@ -171,7 +171,7 @@
     * @param nodeId    èŠ‚ç‚¹id
     * @return ç»“æžœ
     */
    List<ModelNodeIndexInfor> selectIndexByModelCodeAndNodeId(@Param("modelCode") String modelCode, @Param("nodeId") String nodeId);
    List<ModelNodeIndexInfo> selectIndexByModelCodeAndNodeId(@Param("modelCode") String modelCode, @Param("nodeId") String nodeId);
    void delIndexNodeIdAndIndexType(@Param("nodeId")String nodeId, @Param("indexType")String indexType);
@@ -185,7 +185,7 @@
     * @author: hmj
     * @date: 2024/10/16 19:16
     */
    List<ModelNodeIndexInfor> getModelNodeIndexIdByNodeId(@Param("nodeId")String nodeId, @Param("energyType")String energyType);
    List<ModelNodeIndexInfo> getModelNodeIndexIdByNodeId(@Param("nodeId")String nodeId, @Param("energyType")String energyType);
    /**
     * @description: æ ¹æ®nodeId查询子节点的所有统计指标
@@ -194,11 +194,11 @@
     * @author: hmj
     * @date: 2024/10/18 16:12
     */
    List<ModelNodeIndexInfor> getModelNodeByParentId(String parentId);
    List<ModelNodeIndexInfo> getModelNodeByParentId(String parentId);
    ModelNode getFirstModeNodeInfo(String modelCode);
    List<ModelNodeIndexInfor> selectIndexByNodeIds(@Param("modelCode") String modelCode,@Param("nodeIds") List<String> nodeIds);
    List<ModelNodeIndexInfo> selectIndexByNodeIds(@Param("modelCode") String modelCode, @Param("nodeIds") List<String> nodeIds);
    /**
     * æ ¹æ®çˆ¶èŠ‚ç‚¹id和能源类型查询点位下的累积量
zhitan-system/src/main/java/com/zhitan/model/service/IDaqTemplateService.java
@@ -74,6 +74,15 @@
    boolean dapHasExist(DaqTemplate daqTemplate);
    /**
     * æŸ¥è¯¢ç›¸åŒè®¾å¤‡ç±»åž‹ä¸‹æ˜¯å¦æœ‰é‡å¤çš„编码
     *
     * @param code       å‚数编码
     * @param deviceType è®¾å¤‡ç±»åž‹
     * @return æ˜¯å¦å­˜åœ¨
     */
    boolean dapCodeHasExist(String code, String deviceType);
    boolean dapCodeHasExist(DaqTemplate daqTemplate);
    /**
     * æŸ¥è¯¢æŒ‡æ ‡æ¨¡æ¿
     *
     * @return ç»“æžœ
zhitan-system/src/main/java/com/zhitan/model/service/IEnergyIndexService.java
@@ -4,6 +4,7 @@
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.EnergyIndexQuery;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import java.util.List;
@@ -103,7 +104,7 @@
    List<EnergyIndex> searchIndexByNodeAndChildrenNode(String nodeId, String filter);
    void removeNodeIndex(String nodeId, List<String> removeLink);
    void removeEnergyIndex(List<String> removeLink);
    AjaxResult importEnergyIndex(List<EnergyIndex> energyIndexList, boolean updateSupport);
@@ -134,4 +135,11 @@
     * @return
     */
    List<EnergyIndex> listDeviceIndex(String nodeId, String meterId);
    /**
     * æ ¹æ®ç‚¹ä½id获取模型节点点位信息
     * @param indexIds
     * @return
     */
    List<ModelNodeIndexInfo> getModelNodeIndexInfoListByIndexIds(String[] indexIds);
}
zhitan-system/src/main/java/com/zhitan/model/service/IModelNodeService.java
@@ -8,7 +8,7 @@
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.TreeObject;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import java.util.List;
@@ -126,7 +126,7 @@
   * @param code
   * @return
   */
  List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByCode(String code);
  List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByCode(String code);
  /**
   * æ ¹æ®nodeId查询对应详细信息
@@ -134,7 +134,7 @@
   * @param nodeId
   * @return
   */
  List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByNodeId(String nodeId);
  List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByNodeId(String nodeId);
  /**
   * æ ¹æ®çˆ¶id查询详细信息
@@ -142,7 +142,7 @@
   * @param parentId
   * @return
   */
  List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInforByParentId(String parentId);
  List<ModelNodeIndexInfo> listModelNodeIndexIdRelationInforByParentId(String parentId);
  /**
   * æ ¹æ®code查询父级信息
zhitan-system/src/main/java/com/zhitan/model/service/impl/DaqTemplateServiceImpl.java
@@ -114,6 +114,17 @@
        return count > 0;
    }
    @Override
    public boolean dapCodeHasExist(String key, String deviceType) {
        int count = daqTemplateMapper.dapHasExist(key, deviceType);
        return count > 0;
    }
    @Override
    public boolean dapCodeHasExist(DaqTemplate daqTemplate) {
        int count = daqTemplateMapper.dapHasExistWhenUpdate(daqTemplate.getId(), daqTemplate.getGatewayKey(), daqTemplate.getDeviceType());
        return count > 0;
    }
    /**
     * æŸ¥è¯¢æŒ‡æ ‡æ¨¡æ¿
     *
zhitan-system/src/main/java/com/zhitan/model/service/impl/EnergyIndexServiceImpl.java
@@ -1,7 +1,6 @@
package com.zhitan.model.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhitan.basicdata.domain.MeterImplement;
import com.zhitan.basicdata.services.IMeterImplementService;
@@ -12,6 +11,7 @@
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.EnergyIndexQuery;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.EnergyIndexMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.service.IDaqTemplateService;
@@ -212,8 +212,8 @@
    }
    @Override
    public void removeNodeIndex(String nodeId, List<String> removeLink) {
        energyIndexMapper.removeNodeIndex(nodeId, removeLink);
    public void removeEnergyIndex(List<String> removeLink) {
        energyIndexMapper.removeEnergyIndex(removeLink);
    }
    @Override
@@ -345,10 +345,8 @@
     * @return
     */
    public List<EnergyIndex> listDeviceIndexByCode(String nodeId, String meterId, String indexCode) {
        return energyIndexMapper.selectList(Wrappers.<EnergyIndex>lambdaQuery()
                .eq(EnergyIndex::getNodeId, nodeId)
                .eq(EnergyIndex::getMeterId, meterId)
                .like(EnergyIndex::getCode, indexCode));
        List<EnergyIndex> energyIndexList = energyIndexMapper.getIndexByMeterIdIndexCode(meterId,indexCode,nodeId);
        return energyIndexList;
    }
    /**
@@ -360,8 +358,12 @@
     */
    @Override
    public List<EnergyIndex> listDeviceIndex(String nodeId, String meterId) {
        return energyIndexMapper.selectList(Wrappers.<EnergyIndex>lambdaQuery()
                .eq(EnergyIndex::getNodeId, nodeId)
                .eq(EnergyIndex::getMeterId, meterId));
        List<EnergyIndex> energyIndexList = energyIndexMapper.getIndexByMeterIdIndexCode(meterId,null,nodeId);
        return energyIndexList;
    }
    @Override
    public List<ModelNodeIndexInfo> getModelNodeIndexInfoListByIndexIds(String[] indexIds) {
        return energyIndexMapper.getModelNodeIndexInfoListByIndexIds(indexIds);
    }
}
zhitan-system/src/main/java/com/zhitan/model/service/impl/ModelInfoServiceImpl.java
@@ -4,7 +4,7 @@
import com.zhitan.basicdata.services.IMeterImplementService;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelInfo;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.domain.vo.PointDataVO;
import com.zhitan.model.mapper.ModelInfoMapper;
import com.zhitan.model.service.IEnergyIndexService;
@@ -124,16 +124,16 @@
  public List<PointDataVO> listEnergyIndexByModelId(String modelId) {
    List<PointDataVO> voList = new ArrayList<>();
    // æ ¹æ®id查询下级id与indexId
    List<ModelNodeIndexInfor> inforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(modelId);
    List<ModelNodeIndexInfo> inforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(modelId);
    if (CollectionUtils.isEmpty(inforList)) {
      List<ModelNodeIndexInfor> indexInforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelId);
      List<ModelNodeIndexInfo> indexInforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(modelId);
      if (CollectionUtils.isEmpty(indexInforList)) {
        return voList;
      }
      inforList.addAll(indexInforList);
    }
    // åŽ»é™¤æ‰€æœ‰ç‚¹ä½id信息
    List<String> indexIds = inforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
    List<String> indexIds = inforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
    List<EnergyIndex> energyIndexList = energyIndexService.getEnergyIndexByIds(indexIds);
    // æ ¹æ®indexid查询对应计量器具信息
    List<String> meterIds = energyIndexList.stream().map(EnergyIndex::getMeterId).collect(Collectors.toList());
zhitan-system/src/main/java/com/zhitan/model/service/impl/ModelNodeServiceImpl.java
@@ -7,12 +7,11 @@
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.TreeObject;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.service.IEnergyIndexService;
import com.zhitan.model.service.IModelNodeService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -285,7 +284,7 @@
   * @return
   */
  @Override
  public List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByCode(String code) {
  public List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByCode(String code) {
    return modelNodeMapper.getModelNodeIndexIdRelationInforByCode(code);
  }
@@ -296,7 +295,7 @@
   * @return
   */
  @Override
  public List<ModelNodeIndexInfor> getModelNodeIndexIdRelationInforByNodeId(String nodeId) {
  public List<ModelNodeIndexInfo> getModelNodeIndexIdRelationInforByNodeId(String nodeId) {
    return modelNodeMapper.getModelNodeIndexIdRelationInforByNodeId(nodeId);
  }
@@ -307,7 +306,7 @@
   * @return
   */
  @Override
  public List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInforByParentId(String parentId) {
  public List<ModelNodeIndexInfo> listModelNodeIndexIdRelationInforByParentId(String parentId) {
    return modelNodeMapper.listModelNodeIndexIdRelationInforByParentId(parentId);
  }
zhitan-system/src/main/java/com/zhitan/peakvalley/domain/ElectricityPriceDate.java
@@ -32,6 +32,9 @@
    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date endDate;
    private String remark;
//    /** æ˜¯å¦é˜¶æ¢¯ä»·æ ¼0否1是 */
//    @Excel(name = "是否阶梯价格0否1是")
//    private String type;
@@ -121,4 +124,14 @@
            .append("remark", getRemark())
        .toString();
    }
    @Override
    public String getRemark() {
        return remark;
    }
    @Override
    public void setRemark(String remark) {
        this.remark = remark;
    }
}
zhitan-system/src/main/java/com/zhitan/peakvalley/mapper/PeakValleyMapper.java
@@ -38,4 +38,16 @@
    List<ElectricityDataItem> getDataStatisticsDeviationAnalysis(@Param("indexIdSet") Set<String> indexIdSet,
                                                 @Param("timeType") String timeType);
    /**
     * æŸ¥è¯¢æˆæœ¬è¶‹åŠ¿
     * @param beginTime
     * @param endTime
     * @param timeType æ—¶é—´ç±»åž‹
     * @param nodeId èŠ‚ç‚¹Id
     * @param energyType èƒ½æºç±»åž‹
     * @return
     */
    List<ElectricityDataItem> getCostTrends(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                                 @Param("timeType") String timeType, @Param("nodeId") String nodeId,@Param("energyType") String energyType);
}
zhitan-system/src/main/java/com/zhitan/peakvalley/service/IPeakValleyService.java
@@ -41,6 +41,11 @@
     */
    PeakValleyHourVO segmentAnalysisHour(PeakValleyDTO dto);
    /**
     * å°–峰平谷分时统计导出
     * @param dto
     * @return
     */
    List<PeakValleyHourDataVO> segmentAnalysisHourExport(PeakValleyDTO dto);
    PeakValleyDayVO segmentAnalysisDayCustomize(PeakValleyDTO dto);
zhitan-system/src/main/java/com/zhitan/peakvalley/service/impl/PeakValleyServiceImpl.java
@@ -5,9 +5,8 @@
import com.zhitan.common.enums.ElectricityTypeEnum;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.DateUtils;
import com.zhitan.costmanagement.domain.vo.CostPriceRelevancyVo;
import com.zhitan.costmanagement.mapper.CostPriceRelevancyMapper;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.peakvalley.domain.ElectricityDataItem;
import com.zhitan.peakvalley.domain.dto.ElectricityDataItemListDTO;
@@ -56,9 +55,9 @@
        Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
            electricityDataMap = dataItemList.stream()
@@ -131,17 +130,26 @@
        Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            // æ ¹æ®å°æ—¶æ•°æ®è®¡ç®—天的数据
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, TimeType.HOUR.name());
            electricityDataMap = dataItemList.stream()
                    .collect(Collectors.groupingBy(li -> DateUtil.formatDateTime(li.getDataTime())));
        }
        while (!startTime.after(endTime)) {
            String mapKey = DateUtil.formatDateTime(startTime);
            List<ElectricityDataItem> dataItemList = electricityDataMap.get(mapKey);
            Date nextTime = DateUtil.offsetDay(startTime, 1);
            List<ElectricityDataItem> dataItemList = new ArrayList<>();
            for (Map.Entry<String, List<ElectricityDataItem>> entry : electricityDataMap.entrySet()) {
                String key = entry.getKey();
                if ((DateUtils.parseDate(key).after(startTime) || DateUtils.parseDate(key).equals(startTime)) && DateUtils.parseDate(key).before(nextTime)) {
                    List<ElectricityDataItem> list = entry.getValue();
                    dataItemList.addAll(list);
                }
            }
            BigDecimal sharpFee = BigDecimal.ZERO;
            BigDecimal sharpPower = BigDecimal.ZERO;
@@ -157,45 +165,19 @@
                    String electricityType = electricityDataItem.getElectricityType();
                    if (ElectricityTypeEnum.SHARP.name().equals(electricityType)) {
//                        sharpFee = sharpFee.add(electricityDataItem.getCost());
                        sharpFee = sharpFee.add(electricityDataItem.getCost());
                        sharpPower = sharpPower.add(electricityDataItem.getElectricity());
                    } else if (ElectricityTypeEnum.PEAK.name().equals(electricityType)) {
//                        peakFee = peakFee.add(electricityDataItem.getCost());
                        peakFee = peakFee.add(electricityDataItem.getCost());
                        peakPower = peakPower.add(electricityDataItem.getElectricity());
                    } else if (ElectricityTypeEnum.FLAT.name().equals(electricityType)) {
//                        flatFee = flatFee.add(electricityDataItem.getCost());
                        flatFee = flatFee.add(electricityDataItem.getCost());
                        flatPower = flatPower.add(electricityDataItem.getElectricity());
                    } else {
//                        valleyFee = valleyFee.add(electricityDataItem.getCost());
                        valleyFee = valleyFee.add(electricityDataItem.getCost());
                        valleyPower = valleyPower.add(electricityDataItem.getElectricity());
                    }
                }
                //2024-11-12新增
                CostPriceRelevancyVo voS =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.SHARP.name());
                if(voS!=null){
                    sharpFee = voS.getPrice().multiply(sharpPower);
                }
                CostPriceRelevancyVo voP =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.PEAK.name());
                if(voP!=null){
                    peakFee = voP.getPrice().multiply(peakPower);
                }
                CostPriceRelevancyVo voF =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.FLAT.name());
                if(voF!=null){
                    flatFee = voF.getPrice().multiply(flatPower);
                }
                CostPriceRelevancyVo voV =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(), ElectricityTypeEnum.VALLEY.name());
                if(voV!=null){
                    valleyFee = voV.getPrice().multiply(valleyPower);
                }
//                CostPriceRelevancyVo voD =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(), ElectricityTypeEnum.DEEP.name());
//                if(voV!=null){
//                    DeepFee = voV.getPrice().multiply(valleyPower);
//                }
            }
            PeakValleyDayDataVO peakAndValleyReportVO = new PeakValleyDayDataVO(startTime, sharpFee, sharpPower,
                    peakFee, peakPower, flatFee, flatPower, valleyFee, valleyPower);
@@ -329,9 +311,9 @@
        Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
            electricityDataMap = dataItemList.stream()
@@ -355,39 +337,19 @@
                    String electricityType = electricityDataItem.getElectricityType();
                    if (ElectricityTypeEnum.SHARP.name().equals(electricityType)) {
//                        sharpFee = sharpFee.add(electricityDataItem.getCost());
                        sharpFee = sharpFee.add(electricityDataItem.getCost());
                        sharpPower = sharpPower.add(electricityDataItem.getElectricity());
                    } else if (ElectricityTypeEnum.PEAK.name().equals(electricityType)) {
//                        peakFee = peakFee.add(electricityDataItem.getCost());
                        peakFee = peakFee.add(electricityDataItem.getCost());
                        peakPower = peakPower.add(electricityDataItem.getElectricity());
                    } else if (ElectricityTypeEnum.FLAT.name().equals(electricityType)) {
//                        flatFee = flatFee.add(electricityDataItem.getCost());
                        flatFee = flatFee.add(electricityDataItem.getCost());
                        flatPower = flatPower.add(electricityDataItem.getElectricity());
                    } else {
//                        valleyFee = valleyFee.add(electricityDataItem.getCost());
                        valleyFee = valleyFee.add(electricityDataItem.getCost());
                        valleyPower = valleyPower.add(electricityDataItem.getElectricity());
                    }
                }
                //2024-11-12新增
                CostPriceRelevancyVo voS =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.SHARP.name());
                if(voS!=null){
                    sharpFee = voS.getPrice().multiply(sharpPower);
                }
                CostPriceRelevancyVo voP =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.PEAK.name());
                if(voP!=null){
                    peakFee = voP.getPrice().multiply(peakPower);
                }
                CostPriceRelevancyVo voF =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(),ElectricityTypeEnum.FLAT.name());
                if(voF!=null){
                    flatFee = voF.getPrice().multiply(flatPower);
                }
                CostPriceRelevancyVo voV =  costPriceRelevancyMapper.selectCostPriceRelevancyByNodeId(dto.getNodeId(), ElectricityTypeEnum.VALLEY.name());
                if(voV!=null){
                    valleyFee = voV.getPrice().multiply(valleyPower);
                }
            }
            PeakValleyHourDataVO peakAndValleyReportVO = new PeakValleyHourDataVO(startTime, sharpFee, sharpPower,
                    peakFee, peakPower, flatFee, flatPower, valleyFee, valleyPower);
@@ -461,9 +423,9 @@
        Map<String, List<ElectricityDataItem>> electricityDataMap = new HashMap<>();
        // æŸ¥è¯¢ç‚¹ä½ä¿¡æ¯
        List<ModelNodeIndexInfor> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.selectIndexByModelCodeAndNodeId(dto.getModelCode(), dto.getNodeId());
        if (CollectionUtils.isNotEmpty(nodeIndexInfoList)) {
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toSet());
            Set<String> indexSet = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toSet());
            List<ElectricityDataItem> dataItemList = electricityDataItemMapper.getDataStatistics(indexSet, startTime, endTime, timeType);
            electricityDataMap = dataItemList.stream()
zhitan-system/src/main/java/com/zhitan/powerDistribution/domain/PowerDistribution.java
@@ -34,4 +34,6 @@
     * è´Ÿè´£äººç”µè¯
     */
    private String principalsTel;
    private String remark;
}
zhitan-system/src/main/java/com/zhitan/processenergy/domain/DailyProcessEnergy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.zhitan.processenergy.domain;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
@Data
public class DailyProcessEnergy implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    private String timeCode;
    private String unitId;
    @Excel(name = "1时")
    private Double value1;
    @Excel(name = "2时")
    private Double value2;
    @Excel(name = "3时")
    private Double value3;
    @Excel(name = "4时")
    private Double value4;
    @Excel(name = "5时")
    private Double value5;
    @Excel(name = "6时")
    private Double value6;
    @Excel(name = "7时")
    private Double value7;
    @Excel(name = "8时")
    private Double value8;
    @Excel(name = "9时")
    private Double value9;
    @Excel(name = "10时")
    private Double value10;
    @Excel(name = "11时")
    private Double value11;
    @Excel(name = "12时")
    private Double value12;
    @Excel(name = "13时")
    private Double value13;
    @Excel(name = "14时")
    private Double value14;
    @Excel(name = "15时")
    private Double value15;
    @Excel(name = "16时")
    private Double value16;
    @Excel(name = "17时")
    private Double value17;
    @Excel(name = "18时")
    private Double value18;
    @Excel(name = "19时")
    private Double value19;
    @Excel(name = "20时")
    private Double value20;
    @Excel(name = "21时")
    private Double value21;
    @Excel(name = "22时")
    private Double value22;
    @Excel(name = "23时")
    private Double value23;
    @Excel(name = "0时")
    private Double value0;
}
zhitan-system/src/main/java/com/zhitan/processenergy/domain/MonthlyProcessEnergy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,427 @@
package com.zhitan.processenergy.domain;
import com.zhitan.common.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 *工序能耗 æœˆ
 *
 * @author sys
 * @date 2021-01-11
 */
public class MonthlyProcessEnergy implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    private String timeCode;
    @Excel(name = "1日")
    private Double value1;
    @Excel(name = "2日")
    private Double value2;
    @Excel(name = "3日")
    private Double value3;
    @Excel(name = "4日")
    private Double value4;
    @Excel(name = "5日")
    private Double value5;
    @Excel(name = "6日")
    private Double value6;
    @Excel(name = "7日")
    private Double value7;
    @Excel(name = "8日")
    private Double value8;
    @Excel(name = "9日")
    private Double value9;
    @Excel(name = "10日")
    private Double value10;
    @Excel(name = "11日")
    private Double value11;
    @Excel(name = "12日")
    private Double value12;
    @Excel(name = "13日")
    private Double value13;
    @Excel(name = "14日")
    private Double value14;
    @Excel(name = "15日")
    private Double value15;
    @Excel(name = "16日")
    private Double value16;
    @Excel(name = "17日")
    private Double value17;
    @Excel(name = "18日")
    private Double value18;
    @Excel(name = "19日")
    private Double value19;
    @Excel(name = "20日")
    private Double value20;
    @Excel(name = "21日")
    private Double value21;
    @Excel(name = "22日")
    private Double value22;
    @Excel(name = "23日")
    private Double value23;
    @Excel(name = "24日")
    private Double value24;
    @Excel(name = "25日")
    private Double value25;
    @Excel(name = "26日")
    private Double value26;
    @Excel(name = "27日")
    private Double value27;
    @Excel(name = "28日")
    private Double value28;
    @Excel(name = "29日")
    private Double value29;
    @Excel(name = "30日")
    private Double value30;
    @Excel(name = "31日")
    private Double value31;
    private Integer count;
    private String unitId;
    /** æ€»è®°å½•æ•° */
    private long total;
    private List<Map> tablehead =new ArrayList<>();
    private List<MonthlyProcessEnergy> tabledata =new ArrayList<MonthlyProcessEnergy>();
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getUnitId() {
        return unitId;
    }
    public void setUnitId(String unitId) {
        this.unitId = unitId;
    }
    public String getTimeCode() {
        return timeCode;
    }
    public void setTimeCode(String timeCode) {
        this.timeCode = timeCode;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
    public Double getValue1() {
        return value1;
    }
    public void setValue1(Double value1) {
        this.value1 = value1;
    }
    public Double getValue2() {
        return value2;
    }
    public void setValue2(Double value2) {
        this.value2 = value2;
    }
    public Double getValue3() {
        return value3;
    }
    public void setValue3(Double value3) {
        this.value3 = value3;
    }
    public Double getValue4() {
        return value4;
    }
    public void setValue4(Double value4) {
        this.value4 = value4;
    }
    public Double getValue5() {
        return value5;
    }
    public void setValue5(Double value5) {
        this.value5 = value5;
    }
    public Double getValue6() {
        return value6;
    }
    public void setValue6(Double value6) {
        this.value6 = value6;
    }
    public Double getValue7() {
        return value7;
    }
    public void setValue7(Double value7) {
        this.value7 = value7;
    }
    public Double getValue8() {
        return value8;
    }
    public void setValue8(Double value8) {
        this.value8 = value8;
    }
    public Double getValue9() {
        return value9;
    }
    public void setValue9(Double value9) {
        this.value9 = value9;
    }
    public Double getValue10() {
        return value10;
    }
    public void setValue10(Double value10) {
        this.value10 = value10;
    }
    public Double getValue11() {
        return value11;
    }
    public void setValue11(Double value11) {
        this.value11 = value11;
    }
    public Double getValue12() {
        return value12;
    }
    public void setValue12(Double value12) {
        this.value12 = value12;
    }
    public Double getValue13() {
        return value13;
    }
    public void setValue13(Double value13) {
        this.value13 = value13;
    }
    public Double getValue14() {
        return value14;
    }
    public void setValue14(Double value14) {
        this.value14 = value14;
    }
    public Double getValue15() {
        return value15;
    }
    public void setValue15(Double value15) {
        this.value15 = value15;
    }
    public Double getValue16() {
        return value16;
    }
    public void setValue16(Double value16) {
        this.value16 = value16;
    }
    public Double getValue17() {
        return value17;
    }
    public void setValue17(Double value17) {
        this.value17 = value17;
    }
    public Double getValue18() {
        return value18;
    }
    public void setValue18(Double value18) {
        this.value18 = value18;
    }
    public Double getValue19() {
        return value19;
    }
    public void setValue19(Double value19) {
        this.value19 = value19;
    }
    public Double getValue20() {
        return value20;
    }
    public void setValue20(Double value20) {
        this.value20 = value20;
    }
    public Double getValue21() {
        return value21;
    }
    public void setValue21(Double value21) {
        this.value21 = value21;
    }
    public Double getValue22() {
        return value22;
    }
    public void setValue22(Double value22) {
        this.value22 = value22;
    }
    public Double getValue23() {
        return value23;
    }
    public void setValue23(Double value23) {
        this.value23 = value23;
    }
    public Double getValue24() {
        return value24;
    }
    public void setValue24(Double value24) {
        this.value24 = value24;
    }
    public Double getValue25() {
        return value25;
    }
    public void setValue25(Double value25) {
        this.value25 = value25;
    }
    public Double getValue26() {
        return value26;
    }
    public void setValue26(Double value26) {
        this.value26 = value26;
    }
    public Double getValue27() {
        return value27;
    }
    public void setValue27(Double value27) {
        this.value27 = value27;
    }
    public Double getValue28() {
        return value28;
    }
    public void setValue28(Double value28) {
        this.value28 = value28;
    }
    public Double getValue29() {
        return value29;
    }
    public void setValue29(Double value29) {
        this.value29 = value29;
    }
    public Double getValue30() {
        return value30;
    }
    public void setValue30(Double value30) {
        this.value30 = value30;
    }
    public Double getValue31() {
        return value31;
    }
    public void setValue31(Double value31) {
        this.value31 = value31;
    }
    public List<Map> getTablehead() {
        return tablehead;
    }
    public void setTablehead(List<Map> tablehead) {
        this.tablehead = tablehead;
    }
    public List<MonthlyProcessEnergy> getTabledata() {
        return tabledata;
    }
    public void setTabledata(List<MonthlyProcessEnergy> tabledata) {
        this.tabledata = tabledata;
    }
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public long getTotal() {
        return total;
    }
    public void setTotal(long total) {
        this.total = total;
    }
}
zhitan-system/src/main/java/com/zhitan/processenergy/domain/YearProcessEnergy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,237 @@
package com.zhitan.processenergy.domain;
import com.zhitan.common.annotation.Excel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 *工序能耗 æœˆ
 *
 * @author sys
 * @date 2021-01-11
 */
public class YearProcessEnergy implements Serializable {
    private static final long serialVersionUID = 1L;
    private String indexId;
    @Excel(name = "指标名称")
    private String indexName;
    private String value;
    private Date dataTime;
    private String timeType;
    private String timeCode;
    @Excel(name = "1月")
    private Double value1;
    @Excel(name = "2月")
    private Double value2;
    @Excel(name = "3月")
    private Double value3;
    @Excel(name = "4月")
    private Double value4;
    @Excel(name = "5月")
    private Double value5;
    @Excel(name = "6月")
    private Double value6;
    @Excel(name = "7月")
    private Double value7;
    @Excel(name = "8月")
    private Double value8;
    @Excel(name = "9月")
    private Double value9;
    @Excel(name = "10月")
    private Double value10;
    @Excel(name = "11月")
    private Double value11;
    @Excel(name = "12月")
    private Double value12;
    private Integer count;
    private String unitId;
    /** æ€»è®°å½•æ•° */
    private long total;
    private List<Map> tablehead =new ArrayList<>();
    private List<YearProcessEnergy> tabledata =new ArrayList<YearProcessEnergy>();
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getUnitId() {
        return unitId;
    }
    public void setUnitId(String unitId) {
        this.unitId = unitId;
    }
    public String getTimeCode() {
        return timeCode;
    }
    public void setTimeCode(String timeCode) {
        this.timeCode = timeCode;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
    public Double getValue1() {
        return value1;
    }
    public void setValue1(Double value1) {
        this.value1 = value1;
    }
    public Double getValue2() {
        return value2;
    }
    public void setValue2(Double value2) {
        this.value2 = value2;
    }
    public Double getValue3() {
        return value3;
    }
    public void setValue3(Double value3) {
        this.value3 = value3;
    }
    public Double getValue4() {
        return value4;
    }
    public void setValue4(Double value4) {
        this.value4 = value4;
    }
    public Double getValue5() {
        return value5;
    }
    public void setValue5(Double value5) {
        this.value5 = value5;
    }
    public Double getValue6() {
        return value6;
    }
    public void setValue6(Double value6) {
        this.value6 = value6;
    }
    public Double getValue7() {
        return value7;
    }
    public void setValue7(Double value7) {
        this.value7 = value7;
    }
    public Double getValue8() {
        return value8;
    }
    public void setValue8(Double value8) {
        this.value8 = value8;
    }
    public Double getValue9() {
        return value9;
    }
    public void setValue9(Double value9) {
        this.value9 = value9;
    }
    public Double getValue10() {
        return value10;
    }
    public void setValue10(Double value10) {
        this.value10 = value10;
    }
    public Double getValue11() {
        return value11;
    }
    public void setValue11(Double value11) {
        this.value11 = value11;
    }
    public Double getValue12() {
        return value12;
    }
    public void setValue12(Double value12) {
        this.value12 = value12;
    }
    public List<Map> getTablehead() {
        return tablehead;
    }
    public void setTablehead(List<Map> tablehead) {
        this.tablehead = tablehead;
    }
    public List<YearProcessEnergy> getTabledata() {
        return tabledata;
    }
    public void setTabledata(List<YearProcessEnergy> tabledata) {
        this.tabledata = tabledata;
    }
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public long getTotal() {
        return total;
    }
    public void setTotal(long total) {
        this.total = total;
    }
}
zhitan-system/src/main/java/com/zhitan/processenergy/dto/DataItemQueryDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.zhitan.processenergy.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * å‘¨æœŸæ•°æ®é¡¹.
 */
@Data
public class DataItemQueryDTO {
  @ApiModelProperty(value = "指标id")
  private String indexId;
  @ApiModelProperty(value = "模型code")
  private String indexCode;
  @ApiModelProperty(value = "时间字符串")
  private String dataTime;
  @ApiModelProperty(value = "时间类型")
  private String timeType;
  @ApiModelProperty(value = "能源类型")
  private String energyType;
}
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/DailyProcessEnergyMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.zhitan.processenergy.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhitan.processenergy.domain.DailyProcessEnergy;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 */
public interface DailyProcessEnergyMapper extends BaseMapper<DailyProcessEnergy> {
    /**
     *
     * @param indexIds
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<DailyProcessEnergy> getDailyProcessEnergyList(@Param("indexIds") List<String> indexIds,
                                                              @Param("dataList") List<DailyProcessEnergy> dataList,
                                                              @Param("beginTime") Date beginTime,
                                                              @Param("endTime") Date endTime,
                                                              @Param("timeType") String timeType,
                                                              @Param("indexStorageId") String indexStorageId);
    /**
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<DailyProcessEnergy> getListChart(@Param("indexId") String indexId,
                                          @Param("beginTime") Date beginTime,
                                          @Param("endTime") Date endTime,
                                          @Param("timeType") String timeType,
                                          @Param("indexStorageId")  String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/MonthlyProcessEnergyMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.zhitan.processenergy.mapper;
import com.zhitan.processenergy.domain.MonthlyProcessEnergy;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 */
public interface MonthlyProcessEnergyMapper {
    /**
     *
     * @param indexIds
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<MonthlyProcessEnergy> getMonthlyProcessEnergy(@Param("indexIds") List<String> indexIds,
                                                               @Param("dataList") List<MonthlyProcessEnergy> dataList,
                                                               @Param("beginTime") Date beginTime,
                                                               @Param("endTime") Date endTime,
                                                               @Param("timeType") String timeType,
                                                               @Param("indexStorageId") String indexStorageId);
    /**
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<MonthlyProcessEnergy> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") String timeType,
                                            @Param("indexStorageId") String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/processenergy/mapper/YearProcessEnergyMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.zhitan.processenergy.mapper;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.processenergy.domain.YearProcessEnergy;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 */
public interface YearProcessEnergyMapper {
    /**
     *
     * @param indexIds
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<YearProcessEnergy> getYearProcessEnergy(@Param("indexIds") List<String> indexIds,
                                                           @Param("dataList") List<TypeTime> dataList,
                                                           @Param("beginTime") Date beginTime,
                                                           @Param("endTime") Date endTime,
                                                           @Param("timeType") String timeType,
                                                           @Param("indexStorageId") String indexStorageId);
    /**
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @return
     */
    List<YearProcessEnergy> getListChart(@Param("indexId") String indexId,
                                            @Param("beginTime") Date beginTime,
                                            @Param("endTime") Date endTime,
                                            @Param("timeType") String timeType);
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/IDailyProcessEnergyService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.zhitan.processenergy.service;
import com.zhitan.processenergy.domain.DailyProcessEnergy;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
public interface IDailyProcessEnergyService {
    /**
     *
     * @param indexIds
     * @param dataList
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<DailyProcessEnergy> getDailyProcessEnergyList(List<String> indexIds, List<DailyProcessEnergy> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     *
     * @param indexId
     * @param beginTime
     * @param endTime
     * @param timeType
     * @param indexStorageId
     * @return
     */
    List<DailyProcessEnergy> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/IMonthlyProcessEnergyService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.zhitan.processenergy.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.processenergy.domain.MonthlyProcessEnergy;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
public interface IMonthlyProcessEnergyService {
    public List<MonthlyProcessEnergy> getMonthlyProcessEnergy(List<String> indexIds, List<MonthlyProcessEnergy> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    List<MonthlyProcessEnergy> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/IYearProcessEnergyService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.zhitan.processenergy.service;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.processenergy.domain.YearProcessEnergy;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import java.util.Date;
import java.util.List;
/**
 *工序能耗 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
public interface IYearProcessEnergyService {
    List<YearProcessEnergy> getYearProcessEnergy(List<String> indexIds, List<TypeTime> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     *
     * @param queryDto
     * @return
     */
    List<YearProcessEnergy> getListChart(DataItemQueryDTO queryDto);
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/DailyProcessEnergyServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.zhitan.processenergy.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhitan.processenergy.domain.DailyProcessEnergy;
import com.zhitan.processenergy.mapper.DailyProcessEnergyMapper;
import com.zhitan.processenergy.service.IDailyProcessEnergyService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
 *重点设备能耗统计 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
@Service
public class DailyProcessEnergyServiceImpl extends ServiceImpl<DailyProcessEnergyMapper,DailyProcessEnergy> implements IDailyProcessEnergyService {
    @Override
    public List<DailyProcessEnergy> getDailyProcessEnergyList(List<String> indexIds, List<DailyProcessEnergy> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()){
            return baseMapper.getDailyProcessEnergyList(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<DailyProcessEnergy> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return baseMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
        return Collections.emptyList();
    }
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/MonthlyProcessEnergyServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.zhitan.processenergy.service.impl;
import com.zhitan.common.enums.TimeType;
import com.zhitan.processenergy.domain.MonthlyProcessEnergy;
import com.zhitan.processenergy.mapper.MonthlyProcessEnergyMapper;
import com.zhitan.processenergy.service.IMonthlyProcessEnergyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
 *重点设备能耗统计 æ—¥
 *
 * @author sys
 * @date 2021-01-11
 */
@Service
public class MonthlyProcessEnergyServiceImpl implements IMonthlyProcessEnergyService {
    @Resource
    private MonthlyProcessEnergyMapper monthlyProcessEnergyMapper;
    @Override
    public List<MonthlyProcessEnergy> getMonthlyProcessEnergy(List<String> indexIds, List<MonthlyProcessEnergy> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()){
            return monthlyProcessEnergyMapper.getMonthlyProcessEnergy(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    @Override
    public List<MonthlyProcessEnergy> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexId != null && !indexId.isEmpty()) {
            return monthlyProcessEnergyMapper.getListChart(indexId,beginTime,endTime,timeType,indexStorageId);
        }
        return Collections.emptyList();
    }
}
zhitan-system/src/main/java/com/zhitan/processenergy/service/impl/YearProcessEnergyServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.zhitan.processenergy.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.common.utils.TypeTime;
import com.zhitan.processenergy.domain.YearProcessEnergy;
import com.zhitan.processenergy.mapper.YearProcessEnergyMapper;
import com.zhitan.processenergy.service.IYearProcessEnergyService;
import com.zhitan.realtimedata.domain.dto.DataItemQueryDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.annotation.Resources;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
 *重点设备能耗统计 å¹´
 *
 * @author sys
 * @date 2021-01-11
 */
@Service
public class YearProcessEnergyServiceImpl implements IYearProcessEnergyService {
    @Resource
    private YearProcessEnergyMapper yearProcessEnergyMapper;
    @Override
    public List<YearProcessEnergy> getYearProcessEnergy(List<String> indexIds, List<TypeTime> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (indexIds != null && !indexIds.isEmpty()) {
            return yearProcessEnergyMapper.getYearProcessEnergy(indexIds, dataList, beginTime, endTime, timeType, indexStorageId);
        }
        return Collections.emptyList();
    }
    /**
     *
     * @param queryDto
     * @return
     */
    @Override
    public List<YearProcessEnergy> getListChart(DataItemQueryDTO queryDto) {
        if(ObjectUtil.isEmpty(queryDto.getIndexId())) {
            return Collections.emptyList();
        }
        Date convertTime = DateTimeUtil.getTypeTime(queryDto.getTimeType(), queryDto.getDataTime());
        DateTime beginTime = DateUtil.beginOfYear(convertTime);
        DateTime endTime = DateUtil.endOfYear(convertTime);
        return yearProcessEnergyMapper.getListChart(queryDto.getIndexId(),beginTime,endTime,queryDto.getTimeType());
    }
}
zhitan-system/src/main/java/com/zhitan/productoutput/services/impl/ProductOutputServiceImpl.java
@@ -101,6 +101,7 @@
        wrapper.like(StringUtils.isNotEmpty(productOutput.getDataTime()),ProductOutput::getDataTime,productOutput.getDataTime());
        wrapper.eq(StringUtils.isNotEmpty(productOutput.getProductType()),ProductOutput::getProductType,productOutput.getProductType());
        wrapper.eq(StringUtils.isNotEmpty(productOutput.getNodeId()),ProductOutput::getNodeId,productOutput.getNodeId());
        wrapper.eq(StringUtils.isNotEmpty(productOutput.getTimeType()),ProductOutput::getTimeType,productOutput.getTimeType());
        wrapper.orderByDesc(ProductOutput::getCreateTime);
        Page<ProductOutput> page = productOutputMapper.selectPage(new Page<ProductOutput>(pageNum, pageSize), wrapper);
        return page;
zhitan-system/src/main/java/com/zhitan/realtimedata/config/RtdbConfig.java
@@ -19,4 +19,6 @@
  public String token;
  public String bucket;
  public String measurement;
}
zhitan-system/src/main/java/com/zhitan/realtimedata/data/RealtimeDatabaseManager.java
ÎļþÒÑɾ³ý
zhitan-system/src/main/java/com/zhitan/realtimedata/data/influxdb/InfluxDBRepository.java
@@ -147,7 +147,7 @@
        StringBuilder fluxSql = new StringBuilder();
        fluxSql.append("from(bucket: \"").append(config.getBucket()).append("\")")
                .append(timeRange).append("|> filter(fn: (r) => r[\"_measurement\"] == \"")
                .append("meilin\")");
                .append(config.getMeasurement()).append("\")");
        fluxSql.append("|> filter(fn: (r) => r[\"_field\"] == \"value\")");
        if (!tagCodes.isEmpty()) {
            fluxSql.append("|> filter(fn: (r) => r[\"tag\"] =~ /");
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/DataItem.java
@@ -1,7 +1,6 @@
package com.zhitan.realtimedata.domain;
import com.zhitan.common.enums.Quality;
import com.zhitan.common.enums.TimeType;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -17,8 +16,8 @@
  @ApiModelProperty(value = "指标id")
  private String indexId;
  @ApiModelProperty(value = "指标库id")
  private String indexStorageId;
  @ApiModelProperty(value = "能源品种")
  private String energyType;
  @ApiModelProperty(value = "指标code")
  private String indexCode;
  @ApiModelProperty(value = "指标名称")
@@ -32,7 +31,7 @@
  @ApiModelProperty(value = "时间类型编码")
  private String timeCode;
  @ApiModelProperty(value = "时间类型")
  private TimeType timeType;
  private String timeType;
  @ApiModelProperty(value = "值")
  private Double value;
  @ApiModelProperty(value = "质量")
@@ -54,12 +53,12 @@
    this.indexId = indexId;
  }
  public String getIndexStorageId() {
    return indexStorageId;
  public String getEnergyType() {
    return energyType;
  }
  public void setIndexStorageId(String indexStorageId) {
    this.indexStorageId = indexStorageId;
  public void setEnergyType(String energyType) {
    this.energyType = energyType;
  }
  public String getIndexCode() {
@@ -110,11 +109,11 @@
    this.timeCode = timeCode;
  }
  public TimeType getTimeType() {
  public String getTimeType() {
    return timeType;
  }
  public void setTimeType(TimeType timeType) {
  public void setTimeType(String timeType) {
    this.timeType = timeType;
  }
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/WritePoint.java
@@ -8,7 +8,6 @@
/**
 * @author fanxinfu
 */
@Measurement(name = "meilin")
public class WritePoint {
  @Column(tag = true)
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/dto/BranchAnalysisDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.zhitan.realtimedata.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class BranchAnalysisDTO {
    @ApiModelProperty(value="节点id")
    private String nodeId;
    @ApiModelProperty(value ="时间字符串")
    private String dataTime;
    @ApiModelProperty(value ="时间类型")
    private String timeType;
    @ApiModelProperty(value = "能源类型")
    private String energyType;
}
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/dto/DataItemQueryDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.zhitan.realtimedata.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * å‘¨æœŸæ•°æ®é¡¹.
 */
@Data
public class DataItemQueryDTO {
    @ApiModelProperty(value ="指标id")
    private String indexId;
    @ApiModelProperty(value="模型code")
    private String indexCode;
    @ApiModelProperty(value ="时间字符串")
    private String dataTime;
    @ApiModelProperty(value ="时间类型")
    private String timeType;
    @ApiModelProperty(value = "能源类型")
    private String energyType;
}
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/RealtimeDatabaseServiceImpl.java
@@ -6,11 +6,12 @@
import com.zhitan.common.enums.CollectionModes;
import com.zhitan.common.enums.GroupTimeType;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.realtimedata.data.RealtimeDatabaseManager;
import com.zhitan.realtimedata.data.influxdb.InfluxDBRepository;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
import org.apache.commons.collections4.CollectionUtils;
import org.joda.time.DateTime;
import org.joda.time.Seconds;
import org.springframework.stereotype.Service;
import java.util.*;
@@ -23,11 +24,10 @@
    private final InfluxDBRepository repository;
    private final RealtimeDatabaseManager realtimeDatabaseManager;
    public RealtimeDatabaseServiceImpl(InfluxDBRepository repository, RealtimeDatabaseManager realtimeDatabaseManager) {
    public RealtimeDatabaseServiceImpl(InfluxDBRepository repository
    ) {
        this.repository = repository;
        this.realtimeDatabaseManager = realtimeDatabaseManager;
    }
    /**
@@ -115,7 +115,7 @@
    @Override
    public TagValue statistics(String tagCode, Date beginTime, Date endTime, CollectionModes collectionModes) {
        List<TagValue> tagValues = repository.statistics(Collections.singletonList(tagCode), beginTime, endTime, collectionModes);
        return CollectionUtils.isEmpty(tagValues) ? tagValues.get(0) : null;
        return CollectionUtils.isNotEmpty(tagValues) ? tagValues.get(0) : null;
    }
    /**
@@ -169,6 +169,14 @@
    @Override
    public List<TagValue> retrieve(String tagCode, Date beginTime, Date endTime,
                                   RetrievalModes retrievalModes, int pointCount) {
        return realtimeDatabaseManager.retrieve(tagCode, beginTime, endTime, retrievalModes, pointCount);
        repository.getHistoryData(Collections.singletonList(tagCode), beginTime, endTime, pointCount);
        pointCount = retrievalModes == RetrievalModes.Full ? 200 : pointCount;
        int span =
                Seconds.secondsBetween(new DateTime(beginTime), new DateTime(endTime)).getSeconds();
        int interval = span / pointCount;
        List<String> tagCodes = new ArrayList<>();
        tagCodes.add(tagCode);
        List<TagValue> historyData = repository.getHistoryData(tagCodes, beginTime, endTime, interval);
        return historyData;
    }
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/common/DateTimeUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,750 @@
package com.zhitan.statisticalAnalysis.common;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.utils.IntegerUtil;
import com.zhitan.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/**
 * @Description: æ—¶é—´å·¥å…·ç±»
 * @author: yxw
 * @date: 2022å¹´02月02日 12:23
 */
@Slf4j
public class DateTimeUtil {
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼
     */
    public static final String COMMON_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /**
     * æ ¼å¼åŒ–日期到分钟
     */
    public static final String COMMON_PATTERN_END_WITH_MINUTE = "yyyy-MM-dd HH:mm";
    /**
     * æ—¥æœŸæ ¼å¼ - å°æ—¶:分钟
     */
    public static final String COMMON_PATTERN_HOUR_MINUTE = "HH:mm";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å¹´ä»½
     */
    public static final String COMMON_PATTERN_YEAR = "yyyy";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æŸä¸€å¹´,
     */
    public static final String COMMON_PATTERN_CERTAIN_YEAR = "yy";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æœˆä»½
     */
    public static final String COMMON_PATTERN_MONTH = "yyyyMM";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æœˆä»½
     */
    public static final String COMMON_PATTERN_TO_MONTH = "yyyy-MM";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æœˆä»½
     */
    public static final String COMMON_PATTERN_TO_MONTH_WORD = "yyyy-MM月";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æœˆä»½
     */
    public static final String COMMON_PATTERN_TO_MONTH_ZH = "yyyyå¹´MM月";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å¤©
     */
    public static final String COMMON_PATTERN_DAY = "yyyyMMdd";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å¤©
     */
    public static final String COMMON_PATTERN_TO_DAY = "yyyy-MM-dd";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å¤©
     */
    public static final String COMMON_PATTERN_TO_DAY_WORD = "yyyy-MM-dd日";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - æœˆæ—¥
     */
    public static final String COMMON_PATTERN_MONTH_DAY = "MM-dd";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å¤©æŸä¸€å¤©,
     */
    public static final String COMMON_PATTERN_DAY_OF_MONTH = "dd";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å°æ—¶
     */
    public static final String COMMON_PATTERN_HOUR = "yyyyMMddHH";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å°æ—¶
     */
    public static final String COMMON_PATTERN_TO_HOUR = "yyyy-MM-dd HH";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å°æ—¶
     */
    public static final String COMMON_PATTERN_TO_HOUR_WORD = "yyyy-MM-dd HH时";
    /**
     * æ—¥æœŸå¸¸ç”¨æ ¼å¼ - å°æ—¶
     */
    public static final String COMMON_PATTERN_TO_HOUR_TEXT = "yyyyå¹´MM月dd日 HH时";
    /**
     * èŽ·å–å½“å‰æ—¶é—´,时间格式:yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getNowDateTime() {
        return getNowDateTime(COMMON_PATTERN);
    }
    /**
     * èŽ·å–å½“å‰æ—¶é—´
     *
     * @param pattern æ—¶é—´æ ¼å¼
     * @return
     */
    public static String getNowDateTime(String pattern) {
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        String dateTime = df.format(new Date());
        return dateTime;
    }
    /**
     * èŽ·å–ä»Šå¹´çš„å¹´ä»½å€¼
     *
     * @return
     */
    public static String getNowYear() {
        return getNowDateTime(COMMON_PATTERN_YEAR);
    }
    /**
     * èŽ·å–ä»Šå¹´çš„æœˆä»½å€¼
     *
     * @return
     */
    public static String getNowMonth() {
        return getNowDateTime(COMMON_PATTERN_MONTH);
    }
    /**
     * å­—符串转成时间类型,默认格式:yyyy-MM-dd HH:mm:ss
     *
     * @param dateTimeStr
     * @return
     */
    public static Date toDateTime(String dateTimeStr) {
        DateTime dt = null;
        try {
            dt = DateTime.of(dateTimeStr, COMMON_PATTERN);
        } catch (Exception e) {
        }
        return dt;
    }
    /**
     * å­—符串转成时间类型
     *
     * @param dateTimeStr
     * @return
     */
    public static Date toDateTime(String dateTimeStr, String pattern) {
        DateTime dt = null;
        try {
            dt = DateTime.of(dateTimeStr, pattern);
        } catch (Exception e) {
        }
        return dt;
    }
    /**
     * å­—符串转成特定格式的时间字符串类型
     *
     * @param dateTimeStr   æ—¶é—´å­—符串
     * @param sourcePattern å­—符串时间格式
     * @param toPattern     è¦è½¬æˆä»€ä¹ˆæ ¼å¼çš„æ—¶é—´
     * @return
     */
    public static String toDateTimeStr(String dateTimeStr, String sourcePattern, String toPattern) {
        String str = CommonConst.EMPTY;
        try {
            DateTime dt = DateTime.of(dateTimeStr, sourcePattern);
            str = getDateTime(dt, toPattern);
        } catch (Exception e) {
        }
        return str;
    }
    /**
     * æ—¶é—´è½¬æˆæŒ‡å®šçš„æ ¼å¼
     *
     * @param pattern æ—¶é—´æ ¼å¼
     * @return
     */
    public static String getDateTime(Date dt, String pattern) {
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(dt);
    }
    /**
     * æ—¶é—´è½¬æˆyyyy-MM-dd HH:mm:ss格式
     *
     * @return
     */
    public static String getDateTime(Date dt) {
        if (ObjectUtil.isEmpty(dt)) {
            return CommonConst.EMPTY;
        }
        return getDateTime(dt, COMMON_PATTERN);
    }
    /**
     * èŽ·å–å½“å‰æ—¶é—´æ‰€å±žæœˆä»½çš„æœ€åŽä¸€å¤©
     *
     * @return
     */
    public static int getDateTimeLastDay(Date dt) {
        String month = getMonth(dt);
        String firstDate = month + "01";
        Date nextMonthFirstDate = addMonths(toDateTime(firstDate, COMMON_PATTERN_DAY), CommonConst.DIGIT_1);
        Date currentMonthLastDate = addDays(nextMonthFirstDate, CommonConst.DIGIT_MINUS_1);
        int day = IntegerUtil.toInt(getDateTime(currentMonthLastDate, COMMON_PATTERN_DAY_OF_MONTH));
        return day;
    }
    /**
     * èŽ·å–å¹´ä»½å€¼
     *
     * @return
     */
    public static String getYear(Date dt) {
        return getDateTime(dt, COMMON_PATTERN_YEAR);
    }
    /**
     * èŽ·å–æœˆä»½å€¼ 202202
     *
     * @return
     */
    public static String getMonth(Date dt) {
        return getDateTime(dt, COMMON_PATTERN_MONTH);
    }
    /**
     * èŽ·å–å¤©,格式:yyyyMMdd
     *
     * @return
     */
    public static String toDay(Date dt) {
        return getDateTime(dt, COMMON_PATTERN_DAY);
    }
    /**
     * èŽ·å–å°æ—¶:yyyyMMddHH
     *
     * @return
     */
    public static String toHour(Date dt) {
        return getDateTime(dt, COMMON_PATTERN_HOUR);
    }
    /**
     * è½¬æˆå­—符串类型值
     *
     * @return
     */
    public static String toString(Date dt) {
        return getDateTime(dt, COMMON_PATTERN);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„å¹´æ•°
     *
     * @param dateTime
     * @param years
     * @return
     */
    public static Date addYears(Date dateTime, int years) {
        return calcDate(dateTime, years, Calendar.YEAR);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„æœˆæ•°
     *
     * @param dateTime
     * @param months
     * @return
     */
    public static Date addMonths(Date dateTime, int months) {
        return calcDate(dateTime, months, Calendar.MONTH);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„å¤©æ•°
     *
     * @param dateTime
     * @param days
     * @return
     */
    public static Date addDays(Date dateTime, int days) {
        return calcDate(dateTime, days, Calendar.DATE);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„å°æ—¶æ•°
     *
     * @param dateTime
     * @param hours
     * @return
     */
    public static Date addHours(Date dateTime, int hours) {
        return calcDate(dateTime, hours, Calendar.HOUR);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„åˆ†é’Ÿæ•°
     *
     * @param dateTime
     * @param minutes
     * @return
     */
    public static Date addMinutes(Date dateTime, int minutes) {
        return calcDate(dateTime, minutes, Calendar.MINUTE);
    }
    /**
     * æ—¶é—´å¢žåŠ å¯¹åº”çš„å°æ—¶æ•°
     *
     * @param dateTime
     * @param seconds
     * @return
     */
    public static Date addSeconds(Date dateTime, int seconds) {
        return calcDate(dateTime, seconds, Calendar.SECOND);
    }
    /**
     * è®¡ç®—日期通用方法
     *
     * @param dateTime
     * @param addValue
     * @param calendarType è®¡ç®—类型:Calendar.YEAR,Calendar.MONTH,Calendar.DAY
     * @return
     */
    private static Date calcDate(Date dateTime, int addValue, int calendarType) {
        Date dt = null;
        try {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(dateTime);
            //把日期往后增加一年,整数往后推,负数往前移
            calendar.add(calendarType, addValue);
            // èŽ·å–ç›¸åŠ æˆ–è€…ç›¸å‡ä¹‹åŽçš„æ—¶é—´å€¼
            Date tempDt = calendar.getTime();
            // æŠŠæ—¶é—´è½¬æˆæ‰€éœ€è¦çš„æ ¼å¼
            String temp = getDateTime(tempDt, COMMON_PATTERN);
            dt = toDateTime(temp);
        } catch (Exception e) {
        }
        return dt;
    }
    /**
     * èŽ·å–è¯¥æ—¶é—´å±žäºŽå½“å¤©çš„ç¬¬å‡ ä¸ªå°æ—¶
     *
     * @param dateTime
     * @return
     */
    public static int getHourOfDay(Date dateTime) {
        return getDateValue(dateTime, Calendar.HOUR_OF_DAY);
    }
    /**
     * èŽ·å–è¯¥æ—¶é—´å±žäºŽå½“æœˆçš„ç¬¬å‡ å¤©
     *
     * @param dateTime
     * @return
     */
    public static int getDayOfMonth(Date dateTime) {
        return getDateValue(dateTime, Calendar.DAY_OF_MONTH);
    }
    /**
     * èŽ·å–è¯¥æ—¶é—´å±žäºŽå½“å‘¨çš„ç¬¬å‡ å¤©
     * ä¸€å‘¨çš„第一天是周日
     *
     * @param dateTime
     * @return
     */
    public static int getDayOfWeek(Date dateTime) {
        return getDateValue(dateTime, Calendar.DAY_OF_WEEK);
    }
    /**
     * èŽ·å–è¯¥æ—¶é—´å±žäºŽå¹´çš„ç¬¬å‡ ä¸ªæœˆ
     * æœˆä»½å€¼+1是真实的当前月
     *
     * @param dateTime
     * @return å·²ç»åœ¨ç³»ç»Ÿä¸­èŽ·å–å€¼çš„åŸºç¡€ä¸ŠåŠ 1了,现在是真实的当前月份值
     */
    public static int getMonthOfYear(Date dateTime) {
        return getDateValue(dateTime, Calendar.MONTH) + 1;
    }
    /**
     * èŽ·å–å½“å¤©çš„ç¬¬å‡ ä¸ªå°æ—¶/当月的第几天/当年的第几个月
     *
     * @param dateTime     å¦‚果时间值为空,默认当前时间
     * @param calendarType
     * @return
     */
    private static int getDateValue(Date dateTime, int calendarType) {
        int value = 0;
        try {
            if (ObjectUtil.isEmpty(dateTime)) {
                dateTime = new Date();
            }
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(dateTime);
            value = calendar.get(calendarType);
        } catch (Exception e) {
        }
        return value;
    }
    /**
     * å¯¹æ¯”time1 å’Œ time2 çš„大小
     *
     * @param time1
     * @param time2
     * @return -1:time1小于time2;0:time1等于time2;1:time1大于time2;
     */
    public static int compareDateDiff(Date time1, Date time2) {
        long diff = time1.getTime() - time2.getTime();
        int res = 0;
        if (diff > 0) {
            res = 1;
        } else if (diff < 0) {
            res = -1;
        }
        return res;
    }
    /**
     * èŽ·å–æŸ¥è¯¢data_item所需要的timecode值
     *
     * @param timeType æ—¥æœŸç±»åž‹
     * @param date     æ—¶é—´
     * @return
     */
    public static String getTimeCode(String timeType, Date date) {
        String timeCode = CommonConst.EMPTY;
        if (ObjectUtil.isEmpty(date)) {
            date = new Date();
        }
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                timeCode = CommonConst.WORD_H + getDateTime(date, COMMON_PATTERN_HOUR);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                timeCode = CommonConst.WORD_D + getDateTime(date, COMMON_PATTERN_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                timeCode = CommonConst.WORD_M + getDateTime(date, COMMON_PATTERN_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                timeCode = CommonConst.WORD_Y + getDateTime(date, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return timeCode;
    }
    /**
     * èŽ·å–æŸ¥è¯¢æ—¥æœˆå¹´æŠ¥è¡¨æ‰€éœ€è¦çš„timecode值
     *
     * @param timeType æ—¥æœŸç±»åž‹
     * @param date     æ—¶é—´
     * @return
     */
    public static String getReportTimeCode(String timeType, Date date) {
        String timeCode = CommonConst.EMPTY;
        if (ObjectUtil.isEmpty(date)) {
            date = new Date();
        }
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                timeCode = getDateTime(date, COMMON_PATTERN_TO_HOUR);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                timeCode = getDateTime(date, COMMON_PATTERN_TO_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                timeCode = getDateTime(date, COMMON_PATTERN_TO_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                timeCode = getDateTime(date, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return timeCode;
    }
    /**
     * èŽ·å–æ—¶é—´å¯¹åº”çš„çŽ¯æ¯”æ—¶é—´
     *
     * @param timeType HOUR/DAY/MONTH/YEAR
     * @param date     æ—¶é—´å€¼
     * @return
     */
    public static Date getLoopTime(String timeType, Date date) {
        Date dt = null;
        if (ObjectUtil.isEmpty(date)) {
            date = new Date();
        }
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                dt = addHours(date, CommonConst.DIGIT_MINUS_1);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                dt = addDays(date, CommonConst.DIGIT_MINUS_1);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                dt = addMonths(date, CommonConst.DIGIT_MINUS_1);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                dt = addYears(date, CommonConst.DIGIT_MINUS_1);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * èŽ·å–æ•´ç‚¹æ—¶é—´
     *
     * @param timeType HOUR/DAY/MONTH/YEAR
     * @param date     æ—¶é—´å€¼
     * @return
     */
    public static Date getHourTime(String timeType, Date date) {
        Date dt = null;
        if (ObjectUtil.isEmpty(date)) {
            date = new Date();
        }
        String tempStr = null;
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                tempStr = getDateTime(date, COMMON_PATTERN_TO_HOUR);
                dt = toDateTime(tempStr, COMMON_PATTERN_TO_HOUR);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                tempStr = getDateTime(date, COMMON_PATTERN_TO_DAY);
                dt = toDateTime(tempStr, COMMON_PATTERN_TO_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                tempStr = getDateTime(date, COMMON_PATTERN_TO_MONTH);
                dt = toDateTime(tempStr, COMMON_PATTERN_TO_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                tempStr = getDateTime(date, COMMON_PATTERN_YEAR);
                dt = toDateTime(tempStr, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * è®¡ç®—两个时间间隔天数(日期格式比较)
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    public static int daysBetween(Date beginTime, Date endTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginTime);
        long beginStamp = calendar.getTimeInMillis();
        calendar.setTime(endTime);
        long endStamp = calendar.getTimeInMillis();
        long betweenDays = (endStamp - beginStamp) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(betweenDays));
    }
    /**
     * è®¡ç®—两个时间间隔天数(字符串格式比较)
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    public static int daysBetween(String beginTime, String endTime) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date begin = format.parse(beginTime);
            Date end = format.parse(endTime);
            return daysBetween(begin, end);
        } catch (ParseException exception) {
            log.error("计算两个时间间隔天数" + exception.getMessage());
            return 0;
        }
    }
    /**
     * æ ¹æ®æ—¶é—´ç±»åž‹æŠŠå­—符串转成对应的时间
     *
     * @param timeType æ—¶é—´ç±»åž‹
     * @param time     æ—¶é—´å­—符串
     * @return
     */
    public static Date getTime(String timeType, String time) {
        Date dt = null;
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                dt = toDateTime(time, COMMON_PATTERN_TO_HOUR);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                dt = toDateTime(time, COMMON_PATTERN_TO_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                dt = toDateTime(time, COMMON_PATTERN_TO_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                dt = toDateTime(time, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * æ ¹æ®æ—¶é—´ç±»åž‹æŠŠè¿žç»­çš„æ—¥æœŸå­—符串转成对应的时间 ï¼ˆ202303、20230303、2023030301、202303030101)
     *
     * @param timeType æ—¶é—´ç±»åž‹
     * @param time     æ—¶é—´å­—符串
     * @return
     */
    public static Date getTimeByContinuousTimeCode(String timeType, String time) {
        Date dt = null;
        timeType = StringUtil.ifEmptyOrNullReturnValue(timeType).toUpperCase();
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                dt = toDateTime(time, COMMON_PATTERN_HOUR);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                dt = toDateTime(time, COMMON_PATTERN_DAY);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                dt = toDateTime(time, COMMON_PATTERN_MONTH);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                dt = toDateTime(time, COMMON_PATTERN_YEAR);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * æ ¹æ®æ—¶é—´ç±»åž‹è¿”回天、月、年最后的时间
     *
     * @param timeType æ—¶é—´ç±»åž‹
     * @param time     æ—¶é—´
     * @return
     */
    public static Date getEndTimeByType(String timeType, Date time) {
        Date dt = null;
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_DAY:
                dt = DateUtil.endOfDay(time);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                dt = DateUtil.endOfMonth(time);
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                dt = DateUtil.endOfYear(time);
                break;
            default:
                break;
        }
        return dt;
    }
    /**
     * æ ¹æ®å‘¨æœŸç±»åž‹å¯¹ç”Ÿäº§å‘¨æœŸè¿›è¡ŒåŠ å‡è®¡ç®—
     * å¡«æŠ¥å‘¨æœŸç±»åž‹ï¼ˆHOUR小时、DAY天、MONTH月、YEAR年)
     *
     * @param date      ç”Ÿäº§å‘¨æœŸ
     * @param cycleType ç”Ÿäº§å‘¨æœŸç±»åž‹
     * @param cycleType ç”Ÿäº§å‘¨æœŸç±»åž‹
     * @param val è®¡ç®—值
     * @return
     */
    public static Date productionCycleCal(Date date, String cycleType,int val) {
        Date momDate = date;
        switch (cycleType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                momDate = DateUtils.addHours(date, val);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                momDate = DateUtils.addDays(date, val);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                momDate = DateUtils.addMonths(date, val);
                break;
        }
        return momDate;
    }
    /**
     * æ ¹æ®å‘¨æœŸç±»åž‹å¯¹ç”Ÿäº§å‘¨æœŸè¿›è¡ŒåŠ å‡è®¡ç®— å¹¶ä¸”进位  ä¾‹å¦‚: HOUR +1进位就是 åР䏀天
     * å¡«æŠ¥å‘¨æœŸç±»åž‹ï¼ˆHOUR小时、DAY天、MONTH月、YEAR年)
     *
     * @param date      ç”Ÿäº§å‘¨æœŸ
     * @param cycleType ç”Ÿäº§å‘¨æœŸç±»åž‹
     * @param val è®¡ç®—值
     * @return
     */
    public static Date productionCycleCalCarry(Date date, String cycleType,int val) {
        Date momDate = date;
        switch (cycleType) {
            case TimeTypeConst.TIME_TYPE_HOUR:
                momDate = DateUtils.addDays(date, val);
                break;
            case TimeTypeConst.TIME_TYPE_DAY:
                momDate = DateUtils.addMonths(date, val);
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                momDate = DateUtils.addYears(date, val);
                break;
        }
        return momDate;
    }
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/FlowChartsDTO.java
@@ -44,10 +44,13 @@
    /**
     * èŠ‚ç‚¹id
     */
    @NotBlank(message = "节点id不能为空")
    @ApiModelProperty(value = "节点id")
    private String nodeId;
    @NotBlank(message = "模型编码不能为空")
    @ApiModelProperty(value = "模型编码")
    private String modelCode;
    public TimeType getTimeType() {
        if (ObjectUtils.isEmpty(timeType)) {
            return TimeType.DAY;
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/CostTrendEnergyTypeItem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * æˆæœ¬è¶‹åŠ¿-能源类型
 *
 * @Author: Zhujw
 * @Date: 2023/2/14
 */
@Data
@ApiModel(value = "成本趋势-能源类型", description = "成本趋势-能源类型")
public class CostTrendEnergyTypeItem implements Serializable {
    /**
     * èƒ½æºç±»åž‹
     */
    @ApiModelProperty(value = "能源类型")
    private String energyType;
    /**
     * èƒ½æºåç§°
     */
    @ApiModelProperty(value = "能源名称")
    private String energyName;
    /**
     * ç´¯ç§¯é‡
     */
    @ApiModelProperty(value = "累积量")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal accumulation;
    /**
     * è´¹ç”¨
     */
    @ApiModelProperty(value = "费用")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal cost;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyConsumeTrendDetailItem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * è´¹ç”¨åˆ†æž-成本趋势分析统计图返回值信息
 *
 * @Author: Zhujw
 * @Date: 2023/2/14
*/
@Data
@ApiModel(value = "费用分析-成本趋势分析统计图返回值信息", description = "费用分析-成本趋势分析统计图返回值信息")
public class EnergyConsumeTrendDetailItem {
    /**
     *  èƒ½æºç±»åž‹
     */
    @ApiModelProperty(value = "能源类型")
    private String energyType;
    /**
     *  èƒ½æºå•位
     */
    @ApiModelProperty(value = "能源单位")
    private String energyUnit;
    /**
     *  ç´¯ç§¯é‡æ ‡ç­¾
     */
    @ApiModelProperty(value = "累积量标签")
    private String accumulationLabel;
    /**
     *  è´¹ç”¨æ ‡ç­¾
     */
    @ApiModelProperty(value = "费用标签")
    private String costLabel;
    /**
     * ç´¯ç§¯é‡
     */
    @ApiModelProperty(value = "累积量")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal accumulation;
    /**
     * è´¹ç”¨
     */
    @ApiModelProperty(value = "费用")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal cost;
    /**
     * ç´¯ç§¯é‡key集合
     */
    @ApiModelProperty(value = "累积量key集合")
    private List<String> accumulationKeyList;
    /**
     * ç´¯ç§¯é‡value集合
     */
    @ApiModelProperty(value = "累积量value集合")
    private List<BigDecimal> accumulationValueList;
    /**
     * è´¹ç”¨key集合
     */
    @ApiModelProperty(value = "费用key集合")
    private List<String> costKeyList;
    /**
     * è´¹ç”¨value集合
     */
    @ApiModelProperty(value = "费用value集合")
    private List<BigDecimal> costValueList;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyConsumeVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
 * èƒ½è€—实体类
 *
 * @Author: Zhujw
 * @Date: 2023/1/28
 */
@Data
public class EnergyConsumeVO implements Serializable {
    /**
     * è®¡é‡å™¨å…·id
     */
    private String deviceId;
    /**
     * èƒ½æºç±»åž‹
     */
    private String energyType;
    /**
     * æ—¶é—´ç¼–码
     */
    private Date dataTime;
    /**
     * è´¹ç”¨
     */
    private BigDecimal costValue;
    /**
     * ç´¯è®¡é‡
     */
    private BigDecimal accumulationValue;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyCostTrendItem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * æˆæœ¬è¶‹åŠ¿åˆ†æž-表格信息
 *
 * @Author: Zhujw
 * @Date: 2023/2/14
 */
@Data
@ApiModel(value = "成本趋势分析-表格信息", description = "成本趋势分析-表格信息")
public class EnergyCostTrendItem {
    /**
     * ç”¨èƒ½å•å…ƒid
     */
    @ApiModelProperty(value = "用能单元id")
    private String energyUnitId;
    /**
     * ç”¨èƒ½å•元名称
     */
    @ApiModelProperty(value = "用能单元名称")
    private String energyUnitName;
    /**
     * æ€»è´¹ç”¨
     */
    @ApiModelProperty(value = "总费用")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private BigDecimal total;
    /**
     * æ—¶é—´
     */
    @ApiModelProperty(value = "时间")
    private String dateCode;
    /**
     * èƒ½æºç±»åž‹
     */
    @ApiModelProperty(value = "能源类型")
    private List<CostTrendEnergyTypeItem> itemList;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyCostTrendPage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import lombok.Data;
import java.util.List;
/**
 * @Description: TODO
 * @author: yxw
 * @date: 2022å¹´04月15日 10:07
 */
@Data
public class EnergyCostTrendPage {
    /**
     * æ•°æ®åˆ—表
     */
    private List<EnergyCostTrendItem> itemList;
    /**
     * è®°å½•总数量
     */
    private long total;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/EnergyTypeValueContrastedVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * å„能源类型值同比、环比VO
 *
 * @Author: Zhujw
 * @Date: 2023/2/8
 */
@Data
public class EnergyTypeValueContrastedVO {
    /**
     * ç”¨èƒ½å•元名称
     */
    @ApiModelProperty(value = "用能单元名称")
    private String energyUnitName;
    /**
     * èƒ½æºç±»åž‹
     */
    @ApiModelProperty(value = "能源类型")
    private String energyType;
    /**
     * æœ¬æœŸæ—¶é—´
     */
    @ApiModelProperty(value = "本期时间")
    private String currentTime;
    /**
     * æœ¬æœŸå€¼
     */
    @ApiModelProperty(value = "本期值")
    private BigDecimal currentValue;
    /**
     * å¯¹æ¯”æ—¶é—´
     */
    @ApiModelProperty(value = "对比时间")
    private String compareTime;
    /**
     * å¯¹æ¯”值
     */
    @ApiModelProperty(value = "对比值")
    private BigDecimal contrastValues;
    /**
     * åŒæ¯”值
     * åŒæ¯”增长率=(本期值-去年同期值)/去年同期值×100%
     * çŽ¯æ¯”å€¼
     * çŽ¯æ¯”å¢žé•¿çŽ‡=(本期值-上期值)/上期值×100%
     */
    @ApiModelProperty(value = "同比增长率/环比增长率")
    private BigDecimal ratio;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/QueryCompareRequest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
/**
 * @Description: æ•°æ®æŸ¥è¯¢æ¡ä»¶å®žä½“
 * @author: yxw
 * @date: 2022å¹´01月28日 14:49
 */
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="QueryCompareRequest", description="获取数据的参数实体")
public class QueryCompareRequest {
    /**
     * æŸ¥è¯¢æ—¶é—´ç±»åž‹,对应常量类:TimeTypeConst
     */
    @NotBlank(message = "时间类型不能为空")
    @ApiModelProperty(value = "查询时间类型,对应常量:DAY/MONTH/SEASON/YEAR,默认MONTH")
    private String timeType;
    /**
     * æ—¥æœŸå€¼ï¼Œæœˆä»½(202201-202212)、年份(2022-~)
     */
    @NotBlank(message = "时间编码不能为空")
    @ApiModelProperty(value = "日期值,月份(202201-202212)、年份(2022-~)")
    private String timeCode;
    /**
     * èŠ‚ç‚¹Id
     */
    @NotBlank(message = "节点Id")
    @ApiModelProperty(value = "节点Id")
    private String nodeId;
    /**
     * èƒ½æºç±»åž‹ï¼Œé€šè¿‡/隔开,water/gas
     */
    @ApiModelProperty(value = "能源类型,通过/隔开,water/gas")
    private String energyType;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IEnergyConsumeDataService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.zhitan.statisticalAnalysis.service;
import com.zhitan.statisticalAnalysis.domain.vo.*;
import java.util.List;
/**
 * èƒ½æºæ¶ˆè€—统计相关查询
 */
public interface IEnergyConsumeDataService {
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®
     *
     * @param pageNo   é¡µç æ•°
     * @param pageSize æ¯é¡µæ•°æ®å¤šå°‘
     * @param timeCode æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param energyType èƒ½æºç±»åž‹
     * @param modelCode æ¨¡åž‹Code
     * @return
     */
    EnergyCostTrendPage listEnergyCostTrend(int pageNo, int pageSize, String timeCode, String timeType,String energyType, String modelCode);
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰
     *
     * @param timeCode æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param modelCode   æ¨¡åž‹Code
     * @param energyType èƒ½æºç±»åž‹
     * @return
     */
    List<EnergyConsumeTrendDetailItem> listEnergyCostTrendDetail(String timeCode, String timeType, String modelCode, String energyType);
    /**
     * åŒæ¯”环比分析
     *
     * @param req            è¯·æ±‚参数
     * @param comparisonType å¯¹æ¯”类型
     * @return
     */
    public List<EnergyTypeValueContrastedVO> listEnergyTypeYoyInfo(QueryCompareRequest req, String comparisonType);
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/EnergyConsumeDataServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,498 @@
package com.zhitan.statisticalAnalysis.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhitan.basicdata.domain.SysEnergy;
import com.zhitan.basicdata.mapper.SysEnergyMapper;
import com.zhitan.carbonemission.domain.CarbonEmission;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.utils.StringUtils;
import com.zhitan.dataitem.mapper.DataItemMapper;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.NodeIndex;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.mapper.NodeIndexMapper;
import com.zhitan.peakvalley.domain.ElectricityDataItem;
import com.zhitan.peakvalley.mapper.PeakValleyMapper;
import com.zhitan.statisticalAnalysis.common.DateTimeUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import com.zhitan.statisticalAnalysis.domain.vo.*;
import com.zhitan.statisticalAnalysis.service.IEnergyConsumeDataService;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: TODO
 * @author: yxw
 * @date: 2022å¹´04月12日 14:15
 */
@Service
@AllArgsConstructor
public class EnergyConsumeDataServiceImpl implements IEnergyConsumeDataService {
    private DataItemMapper dataItemMapper;
    private ModelNodeMapper modelNodeMapper;
    private NodeIndexMapper nodeIndexMapper;
    private PeakValleyMapper peakValleyMapper;
    private SysEnergyMapper sysEnergyMapper;
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰- èŽ·å–è¡¨æ ¼åˆ—è¡¨æ•°æ®
     *
     * @param pageNo     é¡µç æ•°
     * @param pageSize   æ¯é¡µæ•°æ®å¤šå°‘
     * @param timeCode   æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType   æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param energyType èƒ½æºç±»åž‹
     * @param modelCode  æ¨¡åž‹Code
     * @return
     */
    @Override
    public EnergyCostTrendPage listEnergyCostTrend(int pageNo, int pageSize, String timeCode, String timeType, String energyType,
                                                   String modelCode) {
        //能源类型信息
        SysEnergy sysEnergy = new SysEnergy();
        if (StringUtils.isNotEmpty(energyType)) {
            sysEnergy.setEnersno(energyType);
        }
        List<SysEnergy> sysEnergies = sysEnergyMapper.selectSysEnergyList(sysEnergy);
        if (sysEnergies.isEmpty()) {
            throw new RuntimeException("未查询到能源信息");
        }
        //节点信息
        List<ModelNode> modelNodes = modelNodeMapper.selectList(Wrappers.<ModelNode>lambdaQuery().eq(ModelNode::getModelCode, modelCode)
                .isNull(ModelNode::getParentId));
        if (ObjectUtils.isEmpty(modelNodes)) {
            throw new RuntimeException("未查询到节点信息");
        }
        ModelNode modelNodeInfo = modelNodes.stream().findFirst().get();
        //点位信息
        List<NodeIndex> nodeIndices = nodeIndexMapper.selectList(Wrappers.<NodeIndex>lambdaQuery()
                .eq(NodeIndex::getNodeId, modelNodeInfo.getNodeId()));
        if (nodeIndices.isEmpty()) {
            throw new RuntimeException("未查询到点位信息");
        }
        // æ€»è´¹ç”¨
        BigDecimal totalCost = BigDecimal.ZERO;
        // éåŽ†èƒ½æºç±»åž‹
        List<CostTrendEnergyTypeItem> itemList = new ArrayList<>();
        for (SysEnergy sysEnergyInfo : sysEnergies) {
            CostTrendEnergyTypeItem item = new CostTrendEnergyTypeItem();
            item.setEnergyType(sysEnergyInfo.getEnersno());
            item.setEnergyName(sysEnergyInfo.getEnername());
            // å¤„理时间
            Date bsTime = DateTimeUtil.getTime(timeType, timeCode);
            Date endTime = DateTimeUtil.getEndTimeByType(timeType, bsTime);
            totalCost = getEnergyUnitCostTrendAnalysisValueInfo(timeType, bsTime, endTime, totalCost, nodeIndices, modelNodeInfo.getNodeId(), sysEnergyInfo, item);
            itemList.add(item);
        }
        // éåŽ†ç”¨èƒ½å•å…ƒèŽ·å–è¡¨æ ¼ä¸­çš„æ•°æ®
        List<EnergyCostTrendItem> trendItemList = new ArrayList<>();
        EnergyCostTrendItem energyCostTrendItem = new EnergyCostTrendItem();
        energyCostTrendItem.setDateCode(timeCode);
        energyCostTrendItem.setTotal(totalCost.setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP));
        energyCostTrendItem.setItemList(itemList);
        trendItemList.add(energyCostTrendItem);
        EnergyCostTrendPage energyCostTrendPage = new EnergyCostTrendPage();
        energyCostTrendPage.setTotal(1);
        energyCostTrendPage.setItemList(trendItemList);
        return energyCostTrendPage;
    }
    /**
     * èŽ·å–ç”¨èƒ½å•å…ƒæˆæœ¬è¶‹åŠ¿åˆ†æžç´¯ç§¯é‡ã€è´¹ç”¨ä¿¡æ¯
     *
     * @param timeType      æ—¶é—´ç±»åž‹
     * @param bsTime        å¼€å§‹æ—¶é—´
     * @param endTime       ç»“束时间
     * @param totalCost     æ€»è´¹ç”¨
     * @param nodeIndices   èŠ‚ç‚¹ç‚¹ä½é›†åˆ
     * @param nodeId        èŠ‚ç‚¹id
     * @param sysEnergyInfo èƒ½æºç±»åž‹ä¿¡æ¯
     * @param item          è¿”回对象
     * @return
     */
    private BigDecimal getEnergyUnitCostTrendAnalysisValueInfo(String timeType, Date bsTime, Date endTime, BigDecimal totalCost,
                                                               List<NodeIndex> nodeIndices, String nodeId, SysEnergy sysEnergyInfo,
                                                               CostTrendEnergyTypeItem item) {
        BigDecimal costValue = BigDecimal.ZERO;
        BigDecimal accumulationValue = BigDecimal.ZERO;
        //电:只有HOUR数据有效;其他能源类型:HOUR、DAY有数据
        switch (sysEnergyInfo.getEnersno()) {
            case "electric":
                List<ElectricityDataItem> electricityDataItems = peakValleyMapper.getDataStatistics(nodeIndices.stream().map(NodeIndex::getIndexId).collect(Collectors.toSet()), bsTime, endTime, TimeTypeConst.TIME_TYPE_HOUR);
                costValue = electricityDataItems.stream().map(ElectricityDataItem::getCost).reduce(BigDecimal.ZERO, BigDecimal::add);
                accumulationValue = electricityDataItems.stream().map(ElectricityDataItem::getElectricity).reduce(BigDecimal.ZERO, BigDecimal::add);
                break;
            default:
                accumulationValue = dataItemMapper.getDataItemTimeRangeValueByNodeId(bsTime, endTime, TimeTypeConst.TIME_TYPE_DAY, nodeId, sysEnergyInfo.getEnersno());
                costValue = accumulationValue.multiply(sysEnergyInfo.getPrice());
                break;
        }
        costValue = costValue.setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
        totalCost = totalCost.add(costValue);
        item.setCost(costValue);
        item.setAccumulation(accumulationValue.setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP));
        return totalCost;
    }
    /**
     * æˆæœ¬è¶‹åŠ¿åˆ†æžï¼ˆèƒ½æºæ¶ˆè€—æˆæœ¬ï¼‰
     *
     * @param timeCode   æ—¶é—´å€¼   ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @param timeType   æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param modelCode  æ¨¡åž‹Code
     * @param energyType èƒ½æºç±»åž‹
     * @return
     */
    @Override
    public List<EnergyConsumeTrendDetailItem> listEnergyCostTrendDetail(String timeCode, String timeType, String modelCode, String energyType) {
        //能源类型信息
        SysEnergy sysEnergy = new SysEnergy();
        if (StringUtils.isNotEmpty(energyType)) {
            sysEnergy.setEnersno(energyType);
        }
        List<SysEnergy> sysEnergies = sysEnergyMapper.selectSysEnergyList(sysEnergy);
        if (sysEnergies.isEmpty()) {
            throw new RuntimeException("未查询到能源信息");
        }
        //节点信息
        List<ModelNode> modelNodes = modelNodeMapper.selectList(Wrappers.<ModelNode>lambdaQuery().eq(ModelNode::getModelCode, modelCode)
                .isNull(ModelNode::getParentId));
        if (modelNodes.isEmpty()) {
            throw new RuntimeException("未查询到节点信息");
        }
        String nodeId = modelNodes.stream().findFirst().get().getNodeId();
        // èƒ½è€—信息
        List<EnergyConsumeTrendDetailItem> itemList = new ArrayList<>();
        Date startTime = DateTimeUtil.getTime(timeType, timeCode);
        Date endTime = DateTimeUtil.getEndTimeByType(timeType, startTime);
        //电:只有HOUR数据有效;其他能源类型:HOUR、DAY有数据
        String queryTimeType = TimeTypeConst.TIME_TYPE_HOUR;
        for (SysEnergy sysEnergyInfo : sysEnergies) {
            List<EnergyConsumeVO> energyConsumeVOList = new ArrayList<>();
            switch (sysEnergyInfo.getEnersno()) {
                case "electric":
                    List<ElectricityDataItem> electricityDataItems = peakValleyMapper.getCostTrends(startTime, endTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                    if (!electricityDataItems.isEmpty()) {
                        electricityDataItems.forEach(electricityDataItem -> {
                            EnergyConsumeVO temp = new EnergyConsumeVO();
                            temp.setDataTime(electricityDataItem.getDataTime());
                            temp.setCostValue(electricityDataItem.getCost());
                            temp.setAccumulationValue(electricityDataItem.getElectricity());
                            energyConsumeVOList.add(temp);
                        });
                    }
                    break;
                default:
                    if (timeType.equals(TimeTypeConst.TIME_TYPE_MONTH) || timeType.equals(TimeTypeConst.TIME_TYPE_YEAR)) {
                        queryTimeType = TimeTypeConst.TIME_TYPE_DAY;
                    }
                    List<CarbonEmission> dataItems = dataItemMapper.getMiddleCarbonEmission(startTime, endTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                    if (!dataItems.isEmpty()) {
                        dataItems.forEach(electricityDataItem -> {
                            EnergyConsumeVO temp = new EnergyConsumeVO();
                            temp.setDataTime(electricityDataItem.getDataTime());
                            temp.setCostValue(new BigDecimal(electricityDataItem.getValue()));
                            temp.setAccumulationValue(new BigDecimal(electricityDataItem.getValue()).multiply(sysEnergyInfo.getPrice()));
                            energyConsumeVOList.add(temp);
                        });
                    }
                    break;
            }
            BigDecimal cost = energyConsumeVOList.stream().map(EnergyConsumeVO::getCostValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            BigDecimal accumulation = energyConsumeVOList.stream().map(EnergyConsumeVO::getAccumulationValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            // ç»„装统计图信息
            EnergyConsumeTrendDetailItem item = new EnergyConsumeTrendDetailItem();
            item.setEnergyType(sysEnergyInfo.getEnersno());
            item.setEnergyUnit(sysEnergyInfo.getMuid());
            item.setCostLabel(sysEnergyInfo.getEnername() + "è´¹");
            item.setAccumulationLabel(sysEnergyInfo.getEnername() + "用量");
            item.setCost(cost);
            item.setAccumulation(accumulation);
            // ç»„装图表信息
            getTrendAnalysisCharInfoByEnergyType(startTime, timeType, energyConsumeVOList, item);
            itemList.add(item);
        }
        return itemList;
    }
    /**
     * ç»„装成本趋势分析-统计图信息
     *
     * @param bsTime    æ—¶é—´
     * @param timeType  æ—¶é—´ç±»åž‹
     * @param dataItems èƒ½è€—
     * @param item      è¿”回对象
     */
    private void getTrendAnalysisCharInfoByEnergyType(Date bsTime, String timeType,
                                                      List<EnergyConsumeVO> dataItems, EnergyConsumeTrendDetailItem item) {
        List<String> costKeyList = new ArrayList<>();
        List<String> accumulationKeyList = new ArrayList<>();
        List<BigDecimal> costValueList = new ArrayList<>();
        List<BigDecimal> accumulationValueList = new ArrayList<>();
        Map<String, List<EnergyConsumeVO>> energyConsumeVOMap;
        //按时间类型组织返回数据
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_DAY:
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> DateUtil.formatDateTime(li.getDataTime())));
                for (int i = 0; i < CommonConst.DIGIT_24; i++) {
                    String formatDate = i + CommonConst.TIME_UNIT_SHOW_HOUR;
                    costKeyList.add(formatDate);
                    accumulationKeyList.add(formatDate);
                    String key = DateUtil.formatDateTime(DateUtil.offsetHour(bsTime, i));
                    calculateCostAndAccumulation(energyConsumeVOMap, key, costValueList, accumulationValueList);
                }
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> DateUtil.formatDate(li.getDataTime())));
                Date endTime = DateTimeUtil.getEndTimeByType(timeType, bsTime);
                while (bsTime.before(endTime)) {
                    String formatDate = DateUtil.formatDate(bsTime);
                    costKeyList.add(formatDate);
                    accumulationKeyList.add(formatDate);
                    calculateCostAndAccumulation(energyConsumeVOMap, formatDate, costValueList, accumulationValueList);
                    bsTime = DateUtil.offsetDay(bsTime, CommonConst.DIGIT_1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                SimpleDateFormat formatter = new SimpleDateFormat(DateTimeUtil.COMMON_PATTERN_TO_MONTH_ZH);
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> formatter.format(li.getDataTime())));
                for (int i = 0; i < CommonConst.DIGIT_12; i++) {
                    Date newDate = DateUtil.offsetMonth(bsTime, i);
                    String formatDate = DateUtil.format(newDate, DateTimeUtil.COMMON_PATTERN_TO_MONTH_ZH);
                    costKeyList.add(formatDate);
                    accumulationKeyList.add(formatDate);
                    calculateCostAndAccumulation(energyConsumeVOMap, formatDate, costValueList, accumulationValueList);
                }
                break;
            default:
                break;
        }
        item.setCostKeyList(costKeyList);
        item.setCostValueList(costValueList);
        item.setAccumulationKeyList(accumulationKeyList);
        item.setAccumulationValueList(accumulationValueList);
    }
    /**
     * è®¡ç®—费用和用量
     *
     * @param energyConsumeVOMap
     * @param formatDate
     * @param costValueList
     * @param accumulationValueList
     */
    private static void calculateCostAndAccumulation(Map<String, List<EnergyConsumeVO>> energyConsumeVOMap, String formatDate, List<BigDecimal> costValueList, List<BigDecimal> accumulationValueList) {
        List<EnergyConsumeVO> energyConsumeList = Optional.ofNullable(energyConsumeVOMap.get(formatDate))
                .orElse(Collections.emptyList());
        BigDecimal totalCost = energyConsumeList.stream()
                .map(EnergyConsumeVO::getCostValue)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
        BigDecimal totalAccumulation = energyConsumeList.stream()
                .map(EnergyConsumeVO::getAccumulationValue)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
        costValueList.add(totalCost);
        accumulationValueList.add(totalAccumulation);
    }
    /**
     * åŒæ­¥çŽ¯æ¯”åˆ†æž
     *
     * @param req            è¯·æ±‚参数
     * @param comparisonType å¯¹æ¯”类型
     * @return
     */
    @Override
    public List<EnergyTypeValueContrastedVO> listEnergyTypeYoyInfo(QueryCompareRequest req, String comparisonType) {
        String energyType = req.getEnergyType();
        String timeType = req.getTimeType();
        String timeCode = req.getTimeCode();
        String nodeId = req.getNodeId();
        //能源类型信息
        SysEnergy sysEnergy = new SysEnergy();
        sysEnergy.setEnersno(energyType);
        List<SysEnergy> sysEnergies = sysEnergyMapper.selectSysEnergyList(sysEnergy);
        if (sysEnergies.isEmpty()) {
            throw new RuntimeException("未查询到能源信息");
        }
        SysEnergy sysEnergyInfo = sysEnergies.get(0);
        // èƒ½è€—信息
        Date startTime = DateTimeUtil.getTime(timeType, timeCode);
        Date endTime = DateTimeUtil.getEndTimeByType(timeType, startTime);
        //是否同比
        boolean isYoy = comparisonType.equals(CommonConst.ENERGY_COMPARISON_YOY);
        // è®¡ç®—上一年的同期时间
        Date lastBeginTime = DateUtil.offset(startTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        Date lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        if (!isYoy) {
            switch (timeType) {
                case TimeTypeConst.TIME_TYPE_DAY:
                    lastBeginTime = DateUtil.offsetDay(startTime, CommonConst.DIGIT_MINUS_1);
                    lastEndTime = DateUtil.offsetDay(endTime, CommonConst.DIGIT_MINUS_1);
                    break;
                case TimeTypeConst.TIME_TYPE_MONTH:
                    lastBeginTime = DateUtil.offsetMonth(startTime, CommonConst.DIGIT_MINUS_1);
                    lastEndTime = DateUtil.offsetMonth(endTime, CommonConst.DIGIT_MINUS_1);
                    break;
            }
        }
        //电:只有HOUR数据有效;其他能源类型:HOUR、DAY有数据
        String queryTimeType = TimeTypeConst.TIME_TYPE_HOUR;
        List<EnergyConsumeVO> energyConsumeVOList = new ArrayList<>();
        switch (sysEnergyInfo.getEnersno()) {
            case "electric":
                List<ElectricityDataItem> electricityDataItems = peakValleyMapper.getCostTrends(startTime, endTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                List<ElectricityDataItem> lastDataItemList = peakValleyMapper.getCostTrends(lastBeginTime, lastEndTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                if (!lastDataItemList.isEmpty()) {
                    electricityDataItems.addAll(lastDataItemList);
                }
                if (!electricityDataItems.isEmpty()) {
                    electricityDataItems.forEach(electricityDataItem -> {
                        EnergyConsumeVO temp = new EnergyConsumeVO();
                        temp.setDataTime(electricityDataItem.getDataTime());
                        temp.setAccumulationValue(electricityDataItem.getElectricity());
                        energyConsumeVOList.add(temp);
                    });
                }
                break;
            default:
                if (timeType.equals(TimeTypeConst.TIME_TYPE_MONTH) || timeType.equals(TimeTypeConst.TIME_TYPE_YEAR)) {
                    queryTimeType = TimeTypeConst.TIME_TYPE_DAY;
                }
                List<CarbonEmission> dataItems = dataItemMapper.getMiddleCarbonEmission(startTime, endTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                List<CarbonEmission> lastDataItems = dataItemMapper.getMiddleCarbonEmission(lastBeginTime, lastEndTime, queryTimeType, nodeId, sysEnergyInfo.getEnersno());
                if (!lastDataItems.isEmpty()) {
                    dataItems.addAll(lastDataItems);
                }
                dataItems.addAll(lastDataItems);
                if (!dataItems.isEmpty()) {
                    dataItems.forEach(dataItem -> {
                        EnergyConsumeVO temp = new EnergyConsumeVO();
                        temp.setDataTime(dataItem.getDataTime());
                        temp.setAccumulationValue(new BigDecimal(dataItem.getValue()));
                        energyConsumeVOList.add(temp);
                    });
                }
                break;
        }
        // ç»„装统计图信息
        return getEnergyTypeValueContrastedVOList(startTime, timeType, energyConsumeVOList, sysEnergyInfo.getEnersno(), isYoy);
    }
    /**
     * ç»„装成本趋势分析-统计图信息
     *
     * @param bsTime     æ—¶é—´
     * @param timeType   æ—¶é—´ç±»åž‹
     * @param dataItems  èƒ½è€—
     * @param energyType èƒ½æºç±»åž‹
     * @param isYoy      æ˜¯å¦åŒæ¯”
     */
    private List<EnergyTypeValueContrastedVO> getEnergyTypeValueContrastedVOList(Date bsTime, String timeType,
                                                                                 List<EnergyConsumeVO> dataItems, String energyType, boolean isYoy) {
        Map<String, List<EnergyConsumeVO>> energyConsumeVOMap;
        Map<String, List<EnergyConsumeVO>> lastEnergyConsumeVOMap;
        List<EnergyTypeValueContrastedVO> itemList = new ArrayList<>();
        //按时间类型组织返回数据
        switch (timeType) {
            case TimeTypeConst.TIME_TYPE_DAY:
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> DateUtil.formatDateTime(li.getDataTime())));
                for (int i = 0; i < CommonConst.DIGIT_24; i++) {
                    Date currentTime = DateUtil.offsetHour(bsTime, i);
                    Date compareTime = isYoy ? DateUtil.offset(currentTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1) : DateUtil.offsetDay(currentTime, CommonConst.DIGIT_MINUS_1);
                    String keyCurrentTime = DateUtil.formatDateTime(currentTime);
                    String keyCompareTime = DateUtil.formatDateTime(compareTime);
                    EnergyTypeValueContrastedVO item = getEnergyTypeValueContrastedVO(energyType, energyConsumeVOMap, keyCurrentTime, keyCompareTime, currentTime, compareTime);
                    itemList.add(item);
                }
                break;
            case TimeTypeConst.TIME_TYPE_MONTH:
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> DateUtil.formatDate(li.getDataTime())));
                Date endTime = DateTimeUtil.getEndTimeByType(timeType, bsTime);
                while (bsTime.before(endTime)) {
                    Date currentTime = bsTime;
                    Date compareTime = isYoy ? DateUtil.offset(currentTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1) : DateUtil.offsetMonth(currentTime, CommonConst.DIGIT_MINUS_1);
                    String keyCurrentTime = DateUtil.formatDate(currentTime);
                    String keyCompareTime = DateUtil.formatDate(compareTime);
                    EnergyTypeValueContrastedVO item = getEnergyTypeValueContrastedVO(energyType, energyConsumeVOMap, keyCurrentTime, keyCompareTime, currentTime, compareTime);
                    itemList.add(item);
                    bsTime = DateUtil.offsetDay(bsTime, CommonConst.DIGIT_1);
                }
                break;
            case TimeTypeConst.TIME_TYPE_YEAR:
                SimpleDateFormat formatter = new SimpleDateFormat(DateTimeUtil.COMMON_PATTERN_TO_MONTH_ZH);
                energyConsumeVOMap = dataItems.stream().collect(Collectors.groupingBy(li -> formatter.format(li.getDataTime())));
                for (int i = 0; i < CommonConst.DIGIT_12; i++) {
                    Date currentTime = DateUtil.offsetMonth(bsTime, i);
                    Date compareTime = DateUtil.offset(currentTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
                    String keyCurrentTime = formatter.format(currentTime);
                    String keyCompareTime = formatter.format(compareTime);
                    EnergyTypeValueContrastedVO item = getEnergyTypeValueContrastedVO(energyType, energyConsumeVOMap, keyCurrentTime, keyCompareTime, currentTime, compareTime);
                    itemList.add(item);
                }
                break;
            default:
                break;
        }
        return itemList;
    }
    private @NotNull EnergyTypeValueContrastedVO getEnergyTypeValueContrastedVO(String energyType, Map<String, List<EnergyConsumeVO>> energyConsumeVOMap,
                                                                                String keyCurrentTime, String keyCompareTime, Date currentTime, Date compareTime) {
        List<EnergyConsumeVO> energyConsumeList = Optional.ofNullable(energyConsumeVOMap.get(keyCurrentTime))
                .orElse(Collections.emptyList());
        BigDecimal currentValue = calculateSum(energyConsumeList);
        List<EnergyConsumeVO> lastEnergyConsumeList = Optional.ofNullable(energyConsumeVOMap.get(keyCompareTime))
                .orElse(Collections.emptyList());
        BigDecimal contrastValues = calculateSum(lastEnergyConsumeList);
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        BigDecimal ratio = calculateRatio(currentValue, contrastValues, multiple);
        EnergyTypeValueContrastedVO item = new EnergyTypeValueContrastedVO();
        item.setEnergyType(energyType);
        item.setCurrentTime(DateUtil.formatDateTime(currentTime));
        item.setCompareTime(DateUtil.formatDateTime(compareTime));
        item.setCurrentValue(currentValue);
        item.setContrastValues(contrastValues);
        item.setRatio(ratio);
        return item;
    }
    private BigDecimal calculateSum(List<EnergyConsumeVO> dataItemList) {
        return dataItemList.stream()
                .map(EnergyConsumeVO::getAccumulationValue)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
    }
    private BigDecimal calculateRatio(BigDecimal currentSum, BigDecimal lastSum, BigDecimal multiple) {
        if (lastSum.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return currentSum.subtract(lastSum)
                .divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP)
                .multiply(multiple)
                .setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
    }
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java
@@ -6,7 +6,7 @@
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.enums.TimeType;
import com.zhitan.dataitem.service.IDataItemService;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.realtimedata.domain.DataItem;
import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
@@ -41,14 +41,14 @@
    public List<DataAnalysisYoYVO> listElectricDataComparisonYoY(DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
        // æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        List<ModelNodeIndexInfo> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeInforList)) {
            return yoyList;
        }
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        // èŽ·å–æŸ¥è¯¢æ—¶é—´
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
@@ -62,12 +62,12 @@
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            Optional<ModelNodeIndexInfo> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            yoyVO.setUnit("kWh");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
@@ -93,11 +93,11 @@
    public List<DataAnalysisMoMVO> listElectricDataComparisonMoM(DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = new ArrayList<>();
        // æ ¹æ®id查询点位信息
        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
            return momList;
        }
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        Date lastTime;
@@ -121,8 +121,8 @@
            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        }
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
@@ -130,12 +130,12 @@
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            Optional<ModelNodeIndexInfo> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            momVO.setUnit("kWh");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
@@ -161,14 +161,14 @@
    public List<DataAnalysisYoYVO> listWaterDataComparisonYoY(DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
        // æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        List<ModelNodeIndexInfo> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeInforList)) {
            return yoyList;
        }
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        // æ—¶é—´ç±»åž‹
        // èŽ·å–æŸ¥è¯¢æ—¶é—´
        Date beginTime = dto.getBeginTime();
@@ -183,12 +183,12 @@
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            Optional<ModelNodeIndexInfo> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            yoyVO.setUnit("m³");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
@@ -214,11 +214,11 @@
    public List<DataAnalysisMoMVO> listWaterDataComparisonMoM(DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = new ArrayList<>();
        // æ ¹æ®id查询点位信息
        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        List<ModelNodeIndexInfo> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
            return momList;
        }
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        Date lastTime;
@@ -242,8 +242,8 @@
            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        }
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        Map<String, List<ModelNodeIndexInfo>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfo::getNodeId));
        // æŸ¥è¯¢å¯¹åº”indexIds,找到对应dataItem信息
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
@@ -251,12 +251,12 @@
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            Optional<ModelNodeIndexInfo> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            momVO.setUnit("m³");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
@@ -278,11 +278,11 @@
    /**
     * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
     */
    private List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInfor(String nodeId) {
        List<ModelNodeIndexInfor> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
    private List<ModelNodeIndexInfo> listModelNodeIndexIdRelationInfor(String nodeId) {
        List<ModelNodeIndexInfo> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
        // å¦‚果是空存在两种情况,1:id有问题,2:最底层
        if (CollectionUtils.isEmpty(nodeInforList)) {
            List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
            List<ModelNodeIndexInfo> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
            if (CollectionUtils.isNotEmpty(inforList)) {
                nodeInforList.addAll(inforList);
            }
zhitan-system/src/main/java/com/zhitan/system/mapper/SysRoleMenuMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhitan.system.domain.SysRoleMenu;
import org.apache.ibatis.annotations.Param;
/**
 * è§’色与菜单关联表 æ•°æ®å±‚
@@ -34,7 +35,7 @@
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
     int deleteRoleMenu(Long[] ids);
     int deleteRoleMenu(@Param("ids") Long[] ids);
    /**
     * æ‰¹é‡æ–°å¢žè§’色菜单信息
@@ -42,5 +43,5 @@
     * @param roleMenuList è§’色菜单列表
     * @return ç»“æžœ
     */
     int batchRoleMenu(List<SysRoleMenu> roleMenuList);
     int batchRoleMenu(@Param("list") List<SysRoleMenu> roleMenuList);
}
zhitan-system/src/main/java/com/zhitan/system/service/impl/SysRoleServiceImpl.java
@@ -433,6 +433,7 @@
                    DateUtils.parseDate(role.getParams().get("beginTime")),
                    DateUtils.parseDate(role.getParams().get("endTime")));
        }
        queryWrapper.eq(SysRole::getDelFlag, 0);
        return roleMapper.selectPage(new Page<SysRole>(pageNum,pageSize),queryWrapper);
    }
zhitan-system/src/main/resources/mapper/basicdata/MeterImplementMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.basicdata.mapper.MeterImplementMapper">
    <resultMap type="MeterImplement" id="MeterImplementResult">
    <resultMap type="com.zhitan.basicdata.domain.MeterImplement" id="MeterImplementResult">
        <result property="id"    column="id"    />
        <result property="code"    column="code"    />
        <result property="meterName"    column="meter_name"    />
@@ -31,7 +31,7 @@
        <result property="gatewayId"    column="gateway_id"    />
        <result property="gatewayName"    column="gateway_name"    />
    </resultMap>
    <resultMap type="MeterImplementExcel" id="MeterImplementResultExcel">
    <resultMap type="com.zhitan.basicdata.domain.MeterImplementExcel" id="MeterImplementResultExcel">
        <result property="id"    column="id"    />
        <result property="code"    column="code"    />
        <result property="meterName"    column="meter_name"    />
@@ -59,7 +59,7 @@
        select id,energy_type, code, meter_name, meter_type, model_number, measure_range, manufacturer, person_charge, installaction_location, start_time, check_cycle, reminder_cycle, meter_status, del_flage, remark, putrun_time,create_time, create_by, update_time, update_by,(start_time+check_cycle-reminder_cycle)&lt;=current_date as txflage,wire_diameter,max_allowable_power,gateway_id,gateway_name from meter_implement
    </sql>
    <select id="selectMeterImplementList" parameterType="MeterImplement" resultMap="MeterImplementResult">
    <select id="selectMeterImplementList" parameterType="com.zhitan.basicdata.domain.MeterImplement" resultMap="MeterImplementResult">
        <include refid="selectMeterImplementVo"/>
        <where>
            del_flage='N'
@@ -73,7 +73,7 @@
        order by code
    </select>
    <select id="exectMeterImplementList" parameterType="MeterImplement" resultMap="MeterImplementResultExcel">
    <select id="exectMeterImplementList" parameterType="com.zhitan.basicdata.domain.MeterImplement" resultMap="MeterImplementResultExcel">
        select id,energy_type, code, meter_name, fun_getDiceData('sys_device_type',meter_status) as meter_type, model_number, measure_range, manufacturer,
        person_charge, installaction_location, to_char(start_time,'YYYY-MM-DD') start_time, check_cycle, reminder_cycle, fun_getDiceData('meter_status',meter_status) as meter_status,
        del_flage, remark, create_time, create_by, update_time, update_by,wire_diameter,max_allowable_power,gateway_name
@@ -95,7 +95,7 @@
        where id = #{id}
    </select>
    <select id="selectMeterImplementByCode" parameterType="MeterImplement" resultMap="MeterImplementResult">
    <select id="selectMeterImplementByCode" parameterType="com.zhitan.basicdata.domain.MeterImplement" resultMap="MeterImplementResult">
        <include refid="selectMeterImplementVo"/>
        where code = #{code}
        <if test="id != null  and id != ''"> and id != #{id} or id is null</if>
@@ -133,8 +133,16 @@
            installaction_location = #{installactionLocation}
        </where>
    </select>
    <select id="selectByNodeId" resultType="com.zhitan.basicdata.domain.MeterImplement">
        <include refid="selectMeterImplementVo"/>
        mi
        left join node_device nd on mi.id = nd.device_id
        where
            mi.del_flage = 'N'
            AND nd.node_id = #{nodeId}
    </select>
    <insert id="insertMeterImplement" parameterType="MeterImplement">
    <insert id="insertMeterImplement" parameterType="com.zhitan.basicdata.domain.MeterImplement">
        insert into meter_implement
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null  and id != ''">id,</if>
@@ -192,7 +200,7 @@
         </trim>
    </insert>
    <update id="updateMeterImplement" parameterType="MeterImplement">
    <update id="updateMeterImplement" parameterType="com.zhitan.basicdata.domain.MeterImplement">
        update meter_implement
        <trim prefix="SET" suffixOverrides=",">
            <if test="code != null  and code != ''">code = #{code},</if>
zhitan-system/src/main/resources/mapper/branchanalysis/BranchAnalysisMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.branchanalysis.mapper.BranchAnalysisMapper">
    <resultMap id="dataItemMap" type="com.zhitan.branchanalysis.domain.BranchAnalysisVO">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
    </resultMap>
    <!--全厂能耗统计-->
    <select id="getBranchAnalysisList" resultMap="dataItemMap">
        SELECT
        aa.index_id,
        aa.index_name,
        <foreach item="item" index="index" collection="dataList">
            MAX ( CASE WHEN data_time = #{item.dateTime} THEN "value" END ) AS ${item.value},
        </foreach>
        aa.time_type
        FROM
        (
        SELECT
        ci.index_id,
        ci.NAME AS "index_name",
        di."value",
        di.data_time,
        di.time_type
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        LEFT JOIN facility_archives f ON f."id"=ci.equipment
        WHERE
        di.data_time &gt;= #{beginTime}
        AND di.data_time &lt; #{endTime}
        AND di.index_id IN
        <foreach item="indexId" index="index" collection="indexIds" open="(" separator="," close=")">
            #{indexId}
        </foreach>
        AND di.time_type = #{timeType}
        <if test="indexStorageId !='' and indexStorageId !=null">
            and ci.energy_id=#{indexStorageId}
        </if>
        ) aa
        GROUP BY
        aa.index_id,aa.index_name,aa.time_type
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/comprehensivestatistics/DailyComprehensiveMapper.xml
@@ -39,6 +39,7 @@
        SELECT
            aa.index_id,
            aa.index_name,
            aa.unit_id,
            <foreach item="item" index="index" collection="dataList">
                COALESCE ( MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ), null ) AS ${item.value},
            </foreach>
@@ -49,6 +50,7 @@
            SELECT
                ni.index_id,
                ei."name" AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type,
@@ -68,7 +70,7 @@
                </if>
            ) aa
        GROUP BY
            aa.index_id, aa.index_name, aa.time_type, aa.order_num
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type, aa.order_num
        ORDER BY aa.order_num ASC
    </select>
zhitan-system/src/main/resources/mapper/comprehensivestatistics/MonthlyComprehensiveMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.comprehensivestatistics.mapper.MonthlyComprehensiveMapper">
    <resultMap id="dataItemMap" type="com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
        <result column="value13" property="value13"/>
        <result column="value14" property="value14"/>
        <result column="value15" property="value15"/>
        <result column="value16" property="value16"/>
        <result column="value17" property="value17"/>
        <result column="value18" property="value18"/>
        <result column="value19" property="value19"/>
        <result column="value20" property="value20"/>
        <result column="value21" property="value21"/>
        <result column="value22" property="value22"/>
        <result column="value23" property="value23"/>
        <result column="value24" property="value24"/>
        <result column="value25" property="value25"/>
        <result column="value26" property="value26"/>
        <result column="value27" property="value27"/>
        <result column="value28" property="value28"/>
        <result column="value29" property="value29"/>
        <result column="value30" property="value30"/>
        <result column="value31" property="value31"/>
    </resultMap>
    <!--全厂能耗统计-->
    <select id="getMonthlyComprehensiveList" resultMap="dataItemMap">
        SELECT
            aa.index_id,
            aa.index_name,
            aa.unit_id,
        <foreach item="item" index="index" collection="dataList">
            COALESCE ( MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ), null ) AS ${item.value},
        </foreach>
            aa.time_type,
            aa.order_num orderNum
        FROM
        (
            SELECT
                ni.index_id,
                ei."name" AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type,
                mn.order_num
            FROM
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
            WHERE
                mn.parent_id = #{nodeId}
                AND di.data_time >= #{beginTime}
                AND di.data_time &lt;= #{endTime}
                AND di.time_type = #{timeType}
            <if test="indexStorageId !='' and indexStorageId !=null">
                and ei.energy_id=#{indexStorageId}
            </if>
        ) aa
        GROUP BY
        aa.index_id, aa.index_name, aa.unit_id, aa.time_type, aa.order_num
        ORDER BY aa.order_num ASC
    </select>
    <select id="getListChart" resultMap="dataItemMap">
        SELECT
            di.index_id,
            ci.name AS "index_name",
            ci.unit_id,
            di."value",
            di.data_time,
            di.time_type,
            di.time_code
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        WHERE
            di.index_id =#{indexId}
            AND di.data_time &lt;= #{endTime}
            AND di.data_time >= #{beginTime}
            AND di.time_type = #{timeType}
        ORDER BY
            di.time_code;
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/comprehensivestatistics/YearComprehensiveMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.comprehensivestatistics.mapper.YearComprehensiveMapper">
    <resultMap id="dataItemMap" type="com.zhitan.comprehensivestatistics.domain.YearComperhensive">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
    </resultMap>
    <!--全厂能耗统计-->
    <select id="getYearComprehensiveList" resultMap="dataItemMap">
        SELECT
            aa.index_id,
            aa.index_name,
            aa.unit_id,
            <foreach item="item" index="index" collection="dataList">
                COALESCE ( MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ), null ) AS ${item.value},
            </foreach>
            aa.time_type,
            aa.order_num orderNum
        FROM
        (
            SELECT
                ni.index_id,
                ei."name" AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type,
                mn.order_num
            FROM
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
            WHERE
                mn.parent_id = #{nodeId}
                AND di.data_time >= #{beginTime}
                AND di.data_time &lt;= #{endTime}
                AND di.time_type = #{timeType}
                <if test="indexStorageId !='' and indexStorageId !=null">
                    and ei.energy_id=#{indexStorageId}
                </if>
        ) aa
            GROUP BY aa.index_id, aa.index_name, aa.unit_id, aa.time_type, aa.order_num
            ORDER BY aa.order_num ASC
    </select>
    <select id="getListChart" resultMap="dataItemMap">
        SELECT
            di.index_id,
            ci.name AS "index_name",
            ci.unit_id,
            di."value",
            di.data_time,
            di.time_type,
            di.time_code
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        WHERE
            di.index_id =#{indexId}
            AND di.data_time &lt; #{endTime}
            AND di.data_time >= #{beginTime}
            AND di.time_type = #{timeType}
        ORDER BY
            di.time_code;
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/dailyprocessenergy/DailyProcessEnergyMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.processenergy.mapper.DailyProcessEnergyMapper">
    <resultMap id="dataItemMap" type="com.zhitan.processenergy.domain.DailyProcessEnergy">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
        <result column="value13" property="value13"/>
        <result column="value14" property="value14"/>
        <result column="value15" property="value15"/>
        <result column="value16" property="value16"/>
        <result column="value17" property="value17"/>
        <result column="value18" property="value18"/>
        <result column="value19" property="value19"/>
        <result column="value20" property="value20"/>
        <result column="value21" property="value21"/>
        <result column="value22" property="value22"/>
        <result column="value23" property="value23"/>
        <result column="value0" property="value0"/>
    </resultMap>
    <select id="getDailyProcessEnergyList" resultMap="dataItemMap">
        SELECT
        aa.index_id,
        aa.index_name,
        aa.unit_id,
        <foreach item="item" index="index" collection="dataList">
            MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ) AS ${item.value},
        </foreach>
        aa.time_type
        FROM
        (
            SELECT
                ni.index_id,
                ei.NAME  AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type
            FROM
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
            WHERE
                di.data_time >= #{beginTime}
                AND di.data_time &lt; #{endTime}
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
                AND di.time_type = #{timeType}
                <if test="indexStorageId !='' and indexStorageId !=null">
                    and ei.energy_id=#{indexStorageId}
                </if>
            ) aa
        GROUP BY
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
        SELECT
            di.index_id,
            ci.name AS "index_name",
            ci.unit_id,
            di."value",
            di.data_time,
            di.time_type,
            di.time_code
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        WHERE
            di.index_id =#{indexId}
            AND di.data_time &lt; #{endTime}
            AND di.data_time >= #{beginTime}
            AND di.time_type = #{timeType}
        order by di.data_time
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/dailyprocessenergy/MonthlyProcessEnergyMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.processenergy.mapper.MonthlyProcessEnergyMapper">
    <resultMap id="dataItemMap" type="com.zhitan.processenergy.domain.MonthlyProcessEnergy">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
        <result column="value13" property="value13"/>
        <result column="value14" property="value14"/>
        <result column="value15" property="value15"/>
        <result column="value16" property="value16"/>
        <result column="value17" property="value17"/>
        <result column="value18" property="value18"/>
        <result column="value19" property="value19"/>
        <result column="value20" property="value20"/>
        <result column="value21" property="value21"/>
        <result column="value22" property="value22"/>
        <result column="value23" property="value23"/>
        <result column="value24" property="value24"/>
        <result column="value25" property="value25"/>
        <result column="value26" property="value26"/>
        <result column="value27" property="value27"/>
        <result column="value28" property="value28"/>
        <result column="value29" property="value29"/>
        <result column="value30" property="value30"/>
        <result column="value31" property="value31"/>
    </resultMap>
    <select id="getMonthlyProcessEnergy" resultMap="dataItemMap">
        SELECT
            aa.index_id,
            aa.index_name,
            aa.unit_id,
            <foreach item="item" index="index" collection="dataList">
                MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ) AS ${item.value},
            </foreach>
            aa.time_type
        FROM
        (
            SELECT
                ni.index_id,
                ei.NAME  AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type
            FROM
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
            WHERE
                di.data_time >= #{beginTime}
                AND di.data_time &lt; #{endTime}
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
                AND di.time_type = #{timeType}
                <if test="indexStorageId !='' and indexStorageId !=null">
                    and ei.energy_id=#{indexStorageId}
                </if>
        ) aa
        GROUP BY
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
        SELECT
            di.index_id,
            ci.name AS "index_name",
            ci.unit_id,
            di."value",
            di.data_time,
            di.time_type,
            di.time_code
        FROM
            data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        WHERE
            di.index_id =#{indexId}
          AND di.data_time >= #{beginTime}
          AND di.data_time &lt; #{endTime}
          AND di.time_type = #{timeType}
        order by di.data_time
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/dailyprocessenergy/YearProcessEnergyMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.processenergy.mapper.YearProcessEnergyMapper">
    <resultMap id="dataItemMap" type="com.zhitan.processenergy.domain.YearProcessEnergy">
        <result column="index_id" property="indexId"/>
        <result column="index_name" property="indexName"/>
        <result column="time_type" property="timeType"/>
        <result column="time_code" property="timeCode"/>
        <result column="unit_id" property="unitId"/>
        <result column="value1" property="value1"/>
        <result column="value2" property="value2"/>
        <result column="value3" property="value3"/>
        <result column="value4" property="value4"/>
        <result column="value5" property="value5"/>
        <result column="value6" property="value6"/>
        <result column="value7" property="value7"/>
        <result column="value8" property="value8"/>
        <result column="value9" property="value9"/>
        <result column="value10" property="value10"/>
        <result column="value11" property="value11"/>
        <result column="value12" property="value12"/>
    </resultMap>
    <select id="getYearProcessEnergy" resultMap="dataItemMap">
        SELECT
            aa.index_id,
            aa.index_name,
            aa.unit_id,
            <foreach item="item" index="index" collection="dataList">
                MAX ( CASE WHEN data_time = #{item.dateTime} THEN "value" END ) AS ${item.value},
            </foreach>
            aa.time_type
        FROM
        (
            SELECT
                ni.index_id,
                ei.NAME  AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type
            FROM
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
            WHERE
                di.data_time >= #{beginTime}
                AND di.data_time &lt; #{endTime}
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
                AND di.time_type = #{timeType}
                <if test="indexStorageId !='' and indexStorageId !=null">
                    and ei.energy_id=#{indexStorageId}
                </if>
        ) aa
        GROUP BY
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
        SELECT
            di.index_id,
            ci.name AS "index_name",
            ci.unit_id,
            di."value",
            di.data_time,
            di.time_type,
            di.time_code
        FROM
            data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        WHERE
            di.index_id = #{indexId}
        AND di.time_type = #{timeType}
        <if test="endTime != null">
            AND di.data_time &lt; #{endTime}
        </if>
        <if test="beginTime != null">
            AND di.data_time >= #{beginTime}
        </if>
        order by di.data_time
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml
@@ -215,4 +215,64 @@
        AND ( begin_time BETWEEN #{beginTime} AND #{endTime} )
        AND time_type = #{timeType}
    </select>
    <select id="getDataItemTimeRangeValueByNodeId" resultType="java.math.BigDecimal">
        SELECT
        COALESCE (SUM ( "value" ), 0)
        FROM
        "data_item" di
        JOIN energy_index ei  ON di.index_id = ei.index_id
        WHERE
        di.index_id IN ( SELECT index_id FROM node_index WHERE node_id = #{nodeId})
        <if test="energyType !='' and energyType !=null  and energyType =='allType'">
            AND ei.energy_id != ''
        </if>
        <if test="energyType !='' and energyType !=null  and energyType !='allType'">
            AND  ei.energy_id = #{energyType}
        </if>
        AND (di.data_time BETWEEN #{beginTime} AND #{endTime})
        AND di.time_type = #{timeType}
    </select>
    <select id="getHomePageConsumptionRanking"
            resultType="com.zhitan.consumptionanalysis.domain.vo.RankingEnergyData">
        SELECT
            A.node_Id,
            A."name" AS nodeName,
            A.energy_id AS energyTypeNo,
            A.index_type AS energyTypeName,
            A."value" AS energyConsumption
        FROM
        (
            SELECT
                mn.node_id,
                mn."name",
                ei.energy_id,
                ei.index_type,
                se.coefficient,
                (SUM ( di."value" ) * se.coefficient) AS "value"
            FROM
                model_node mn
            LEFT JOIN node_index ni ON ni.node_id = mn.node_id
            LEFT JOIN data_item di ON di.index_id = ni.index_id
            LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
            LEFT JOIN sys_energy se ON se.enersno = ei.energy_id
            WHERE
                mn.node_id IN
                <foreach collection="nodeIds" item="nodeId" open="(" separator="," close=")">
                    #{nodeId}
                </foreach>
                AND di.time_type = #{timeType}
                AND di.begin_time between #{beginTime} AND #{endTime}
                AND ei.index_type = 'STATISTIC'
            GROUP BY
                mn.node_id,
                mn."name",
                ei.energy_id,
                ei.index_type,
                se.coefficient
        ) A
        ORDER BY
            A."value" DESC
        LIMIT 5
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/energyData/EnergyDataMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.energydata.mapper.EnergyDataStatisticMapper">
    <select id="getModelNodeIndexIdByFixedNodeIds" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
    <select id="getModelNodeIndexIdByFixedNodeIds" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId,
zhitan-system/src/main/resources/mapper/keyequipment/DailyKeyEquipmentMapper.xml
@@ -38,6 +38,7 @@
        SELECT
        aa.index_id,
        aa.index_name,
            aa.unit_id,
        <foreach item="item" index="index" collection="dataList">
            MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ) AS ${item.value},
        </foreach>
@@ -45,25 +46,31 @@
        FROM
        (
        SELECT
        ci.index_id,
        ci.NAME  AS "index_name",
                ni.index_id,
                ei.NAME  AS "index_name",
                ei.unit_id,
        di."value",
        di.data_time,
        di.time_type
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        LEFT JOIN facility_archives f ON f."id"=ci.equipment
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
        WHERE
        di.data_time >= #{beginTime}
        AND di.data_time &lt; #{endTime}
        AND di.index_id IN <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">#{indexId} </foreach>
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
        AND di.time_type = #{timeType}
        <if test="indexStorageId !='' and indexStorageId !=null">
            and ci.equipment=#{indexStorageId}
                    and ei.energy_id=#{indexStorageId}
        </if>
        ) aa
        GROUP BY
        aa.index_id,aa.index_name,aa.time_type
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
zhitan-system/src/main/resources/mapper/keyequipment/MonthlyKeyEquipmentMapper.xml
@@ -46,6 +46,7 @@
        SELECT
        aa.index_id,
        aa.index_name,
        aa.unit_id,
        <foreach item="item" index="index" collection="dataList">
            MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ) AS ${item.value},
        </foreach>
@@ -53,25 +54,31 @@
        FROM
        (
        SELECT
        ci.index_id,
        ci.NAME  AS "index_name",
                ni.index_id,
                ei.NAME  AS "index_name",
                ei.unit_id,
        di."value",
        di.data_time,
        di.time_type
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        LEFT JOIN facility_archives f ON f."id"=ci.equipment
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
        WHERE
        di.data_time >= #{beginTime}
        AND di.data_time &lt; #{endTime}
        AND di.index_id IN <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">#{indexId} </foreach>
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
        AND di.time_type = #{timeType}
        <if test="indexStorageId !='' and indexStorageId !=null">
            and ci.equipment=#{indexStorageId}
                    and ei.energy_id=#{indexStorageId}
        </if>
        ) aa
        GROUP BY
        aa.index_id,aa.index_name,aa.time_type
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
zhitan-system/src/main/resources/mapper/keyequipment/YearKeyEquipmentMapper.xml
@@ -27,32 +27,39 @@
        SELECT
        aa.index_id,
        aa.index_name,
            aa.unit_id,
        <foreach item="item" index="index" collection="dataList">
            MAX ( CASE WHEN data_time = #{item.dataTime} THEN "value" END ) AS ${item.value},
                MAX ( CASE WHEN data_time = #{item.dateTime} THEN "value" END ) AS ${item.value},
        </foreach>
        aa.time_type
        FROM
        (
        SELECT
        ci.index_id,
        ci.NAME  AS "index_name",
                ni.index_id,
                ei.NAME AS "index_name",
                ei.unit_id,
        di."value",
        di.data_time,
        di.time_type
        FROM
        data_item di LEFT JOIN energy_index ci ON di.index_id = ci.index_id
        LEFT JOIN facility_archives f ON f."id"=ci.equipment
                model_node mn
                LEFT JOIN node_index ni ON ni.node_id = mn.node_id
                LEFT JOIN energy_index ei ON ei.index_id = ni.index_id
                LEFT JOIN data_item di ON ni.index_id = di.index_id
        WHERE
        di.data_time >= #{beginTime}
                di.data_time &gt;= #{beginTime}
        AND di.data_time &lt; #{endTime}
        AND di.index_id IN <foreach item="indexId" index="index" collection="indexIds"  open="(" separator="," close=")">#{indexId} </foreach>
                AND di.index_id IN
                    <foreach item="indexId" index="index" collection="indexIds" open="(" separator="," close=")">
                        #{indexId}
                    </foreach>
        AND di.time_type = #{timeType}
        <if test="indexStorageId !='' and indexStorageId !=null">
            and ci.equipment=#{indexStorageId}
                    and ei.energy_id=#{indexStorageId}
        </if>
        ) aa
        GROUP BY
        aa.index_id,aa.index_name,aa.time_type
            aa.index_id, aa.index_name, aa.unit_id, aa.time_type
    </select>
    <select id="getListChart" resultMap="dataItemMap">
@@ -69,8 +76,12 @@
        WHERE
            di.index_id =#{indexId}
            AND di.data_time &lt; #{endTime}
            AND di.data_time >= #{beginTime}
        <if test="endTime != null">
            AND di.data_time &gt;= #{beginTime}
        </if>
        <if test="beginTime != null">
            AND di.time_type = #{timeType}
        </if>
        order by di.data_time
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/model/DaqTemplateMapper.xml
@@ -10,10 +10,11 @@
        <result property="name" column="name"/>
        <result property="deviceType" column="device_type"/>
        <result property="unit" column="unit"/>
        <result property="gatewayKey" column="gateway_key"/>
    </resultMap>
    <sql id="selectDaqTemplateVo">
        select id, code, name, device_type, unit
        select id, code, name, device_type, unit, gateway_key
        from daq_template
    </sql>
@@ -44,6 +45,19 @@
          AND device_type = #{deviceType}
          AND id != #{id}
    </select>
    <select id="dapCodeHasExist" resultType="java.lang.Integer">
        SELECT COUNT(*)
        FROM daq_template
        WHERE gateway_key = #{key}
          AND device_type = #{deviceType}
    </select>
    <select id="dapCodeHasExistWhenUpdate" resultType="java.lang.Integer">
        SELECT COUNT(*)
        FROM daq_template
        WHERE gateway_key = #{key}
          AND device_type = #{deviceType}
          AND id != #{id}
    </select>
    <select id="listTemplate" resultType="com.zhitan.model.domain.DaqTemplate">
        <include refid="selectDaqTemplateVo"/>
    </select>
@@ -56,6 +70,7 @@
            <if test="name != null  and name != ''">name,</if>
            <if test="deviceType != null  and deviceType != ''">device_type,</if>
            <if test="unit != null  and unit != ''">unit,</if>
            <if test="gatewayKey != null  and gatewayKey != ''">gateway_key,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null  and id != ''">#{id},</if>
@@ -63,6 +78,7 @@
            <if test="name != null  and name != ''">#{name},</if>
            <if test="deviceType != null  and deviceType != ''">#{deviceType},</if>
            <if test="unit != null  and unit != ''">#{unit},</if>
            <if test="gatewayKey != null  and gatewayKey != ''">#{gatewayKey},</if>
        </trim>
    </insert>
@@ -73,6 +89,7 @@
            <if test="name != null  and name != ''">name = #{name},</if>
            <if test="deviceType != null  and deviceType != ''">device_type = #{deviceType},</if>
            <if test="unit != null  and unit != ''">unit = #{unit},</if>
            <if test="gatewayKey != null  and gatewayKey != ''">gateway_key = #{gatewayKey},</if>
        </trim>
        where id = #{id}
    </update>
zhitan-system/src/main/resources/mapper/model/EnergyIndexMapper.xml
@@ -303,11 +303,11 @@
    from energy_index
    where meter_id = #{meterId}
  </delete>
  <delete id="removeNodeIndex">
    delete from node_index where node_id = #{nodeId} and index_id in
    <foreach item="indexId" collection="indexIds" open="(" separator="," close=")">
  <delete id="removeEnergyIndex">
    delete from energy_index where index_id in
    <foreach collection="indexIds" item="indexId" open="(" separator="," close=")">
      #{indexId}
    </foreach>;
    </foreach>
  </delete>
  <select id="getEnergyIndexMeterByCodes" resultMap="EnergyIndexResult">
@@ -391,4 +391,40 @@
        </if>
    </where>
  </select>
  <select id="getIndexByMeterIdIndexCode" resultType="com.zhitan.model.domain.EnergyIndex">
    SELECT ei.code,mi.meter_name||'_'||ei.name as name from energy_index ei
    LEFT JOIN node_device nd on ei.meter_id =  nd.device_id
    LEFT JOIN meter_implement  mi on mi."id" = nd.device_id
    <where>
        <if test="nodeId != null  and nodeId != ''">and nd.node_id  = #{nodeId}</if>
        <if test="indexCode != null  and indexCode != ''">
          and (mi.meter_name like concat('%', #{indexCode}, '%')
          or ei.code like concat('%', #{indexCode}, '%')
          or ei.name like concat('%', #{indexCode}, '%')
          )
        </if>
        <if test="meterId != null  and meterId != ''">
          and ei.meter_id = #{meterId}
        </if>
    </where>
  </select>
    <select id="getModelNodeIndexInfoListByIndexIds"
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT     mi.model_name modelName,
          mi.model_code,
          mn."name" "name",
          ei.index_id,
          ei.code indexCode,
          ei."name" indexName,
          ei.energy_id,
          ei.energy_id
        FROM node_index ni
        INNER JOIN energy_index ei ON ni.index_id = ei.index_id
        LEFT JOIN model_node mn ON ni.node_id = mn.node_id
        LEFT JOIN model_info mi ON mn.model_code = mi.model_code
        WHERE ei.index_id IN
        <foreach collection="indexIds" item="indexId" open="(" separator="," close=")">
            #{indexId}
        </foreach>
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/model/ModelNodeMapper.xml
@@ -292,7 +292,7 @@
    </select>
    <select id="getModelNodeIndexIdRelationInforByCode"
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId
@@ -303,7 +303,7 @@
    </select>
    <select id="listModelNodeIndexIdRelationInforByParentId"
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId
@@ -313,7 +313,7 @@
    </select>
    <select id="getModelNodeIndexIdRelationInforByNodeId"
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId
@@ -336,7 +336,7 @@
        LIMIT 1;
    </select>
    <select id="selectIndexByModelCodeAndNodeId"
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
            resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name",
               ni.index_id indexId
@@ -380,12 +380,13 @@
        </foreach>
    </insert>
    <select id="getModelNodeIndexIdByNodeId" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
    <select id="getModelNodeIndexIdByNodeId" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id nodeId,
        mn."name" "name",
        ni.index_id indexId,
        ei.energy_id energyId,
        ei.index_type indexType
        ei.index_type indexType,
        ei.unit_id unitId
        FROM "model_node" mn
        LEFT JOIN "node_index" ni ON mn.node_id = ni.node_id
        LEFT JOIN energy_index ei on ni.index_id = ei.index_id
@@ -394,7 +395,7 @@
            and ei.energy_id = #{energyType}
        </if>
    </select>
    <select id="getModelNodeByParentId" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
    <select id="getModelNodeByParentId" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId,
@@ -410,7 +411,7 @@
        where model_code = #{modelCode} AND parent_id is null
        order by order_num
    </select>
    <select id="selectIndexByNodeIds" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfor">
    <select id="selectIndexByNodeIds" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT mn.node_id nodeId,
        mn."name" "name",
        ni.index_id indexId,
zhitan-system/src/main/resources/mapper/peakvalley/ElectricityDataItemMapper.xml
@@ -49,4 +49,30 @@
        AND time_type = #{timeType}
    </select>
    <select id="getCostTrends"
            resultType="com.zhitan.peakvalley.domain.ElectricityDataItem">
        SELECT
        di.index_code,
        di.time_code,
        di.electricity_type,
        di.data_time,
        di.electricity,
        di.cost,
        di.time_type,
        di.price,
        di.remark
        FROM
        "electricity_data_item" di
        JOIN energy_index ei  ON di.index_id = ei.index_id
        WHERE
        di.index_id IN ( SELECT index_id FROM node_index WHERE node_id = #{nodeId})
        <if test="energyType !='' and energyType !=null  and energyType =='allType'">
            AND ei.energy_id != ''
        </if>
        <if test="energyType !='' and energyType !=null  and energyType !='allType'">
            AND  ei.energy_id = #{energyType}
        </if>
        AND (di.data_time BETWEEN #{beginTime} AND #{endTime})
        AND di.time_type = #{timeType}
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/system/SysConfigMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.system.mapper.SysConfigMapper">
    
    <resultMap type="SysConfig" id="SysConfigResult">
    <resultMap type="com.zhitan.system.domain.SysConfig" id="SysConfigResult">
        <id     property="configId"      column="config_id"      />
        <result property="configName"    column="config_name"    />
        <result property="configKey"     column="config_key"     />
@@ -63,6 +63,10 @@
        <include refid="selectConfigVo"/>
        where config_key = #{configKey}
    </select>
    <select id="selectConfigById" resultType="com.zhitan.system.domain.SysConfig">
        <include refid="selectConfigVo"/>
        where config_id = #{configId}
    </select>
    
    <insert id="insertConfig" parameterType="SysConfig">
        insert into sys_config (
zhitan-system/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.system.mapper.SysRoleMapper">
    <resultMap type="SysRole" id="SysRoleResult">
    <resultMap type="com.zhitan.common.core.domain.entity.SysRole" id="SysRoleResult">
        <id     property="roleId"       column="role_id"        />
        <result property="roleName"     column="role_name"      />
        <result property="roleKey"      column="role_key"       />
@@ -30,7 +30,7 @@
            left join sys_dept d on u.dept_id = d.dept_id
    </sql>
    
    <select id="selectRoleList" parameterType="SysRole" resultMap="SysRoleResult">
    <select id="selectRoleList" parameterType="com.zhitan.common.core.domain.entity.SysRole" resultMap="SysRoleResult">
        <include refid="selectRoleVo"/>
        where r.del_flag = '0'
        <if test="roleId != null and roleId != 0">
@@ -94,7 +94,7 @@
         where r.role_key=#{roleKey} and r.del_flag = '0' limit 1
    </select>
    
     <insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId">
     <insert id="insertRole" parameterType="com.zhitan.common.core.domain.entity.SysRole" useGeneratedKeys="true" keyProperty="roleId">
         insert into sys_role(
             <if test="roleId != null and roleId != 0">role_id,</if>
             <if test="roleName != null and roleName != ''">role_name,</if>
@@ -122,7 +122,7 @@
         )
    </insert>
    
    <update id="updateRole" parameterType="SysRole">
    <update id="updateRole" parameterType="com.zhitan.common.core.domain.entity.SysRole">
         update sys_role
         <set>
             <if test="roleName != null and roleName != ''">role_name = #{roleName},</if>
@@ -139,7 +139,7 @@
         where role_id = #{roleId}
    </update>
    
    <update id="updateRoleStatus" parameterType="SysRole">
    <update id="updateRoleStatus" parameterType="com.zhitan.common.core.domain.entity.SysRole">
         update sys_user set status = #{status} where user_id = #{userId}
    </update>
    
zhitan-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
@@ -4,7 +4,7 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.system.mapper.SysRoleMenuMapper">
    <resultMap type="SysRoleMenu" id="SysRoleMenuResult">
    <resultMap type="com.zhitan.system.domain.SysRoleMenu" id="SysRoleMenuResult">
        <result property="roleId"     column="role_id"      />
        <result property="menuId"     column="menu_id"      />
    </resultMap>
@@ -16,6 +16,13 @@
    <delete id="deleteRoleMenuByRoleId" parameterType="Long">
        delete from sys_role_menu where role_id=#{roleId}
    </delete>
    <delete id="deleteRoleMenu" parameterType="arraylist">
        delete from sys_role_menu where role_id in (
        <foreach collection="ids" item="roleId" separator=",">
            #{roleId}
        </foreach>
        )
    </delete>
    
    <insert id="batchRoleMenu">
        insert into sys_role_menu(role_id, menu_id) values
zhitan-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -4,7 +4,7 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.system.mapper.SysUserMapper">
    <resultMap type="SysUser" id="SysUserResult">
    <resultMap type="com.zhitan.common.core.domain.entity.SysUser" id="SysUserResult">
        <id property="userId" column="user_id"/>
        <result property="deptId" column="dept_id"/>
        <result property="userName" column="user_name"/>
@@ -24,11 +24,11 @@
        <result property="updateTime" column="update_time"/>
        <result property="remark" column="remark"/>
        <result property="singleUser" column="single_user"/>
        <association property="dept"    javaType="SysDept"         resultMap="deptResult" />
        <association property="dept" javaType="com.zhitan.common.core.domain.entity.SysDept" resultMap="deptResult"/>
        <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
    </resultMap>
    <resultMap id="deptResult" type="SysDept">
    <resultMap id="deptResult" type="com.zhitan.common.core.domain.entity.SysDept">
        <id property="deptId" column="dept_id"/>
        <result property="parentId" column="parent_id"/>
        <result property="deptName" column="dept_name"/>
@@ -38,7 +38,7 @@
        <result property="status" column="dept_status"/>
    </resultMap>
    <resultMap id="RoleResult" type="SysRole">
    <resultMap id="RoleResult" type="com.zhitan.common.core.domain.entity.SysRole">
        <id property="roleId" column="role_id"/>
        <result property="roleName" column="role_name"/>
        <result property="roleKey" column="role_key"/>
@@ -84,9 +84,10 @@
                 left join sys_role r on r.role_id = ur.role_id
    </sql>
    <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
    <select id="selectUserList" parameterType="com.zhitan.common.core.domain.entity.SysUser" resultMap="SysUserResult">
        select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phone_number, u.password, u.sex,
        u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.single_user, d.dept_name, d.leader from
        u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.single_user, d.dept_name,
        d.leader from
        sys_user u
        left join sys_dept d on u.dept_id = d.dept_id
        where u.del_flag = '0'
@@ -124,18 +125,63 @@
    </select>
    <select id="checkUserNameUnique" parameterType="String" resultMap="SysUserResult">
        select user_id, user_name from sys_user where user_name = #{userName} and del_flag = '0' limit 1
        select user_id, user_name
        from sys_user
        where user_name = #{userName}
          and del_flag = '0' limit 1
    </select>
    <select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
        select user_id, phone_number from sys_user where phone_number = #{phoneNumber} and del_flag = '0' limit 1
        select user_id, phone_number
        from sys_user
        where phone_number = #{phoneNumber}
          and del_flag = '0' limit 1
    </select>
    <select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
        select user_id, email from sys_user where email = #{email} and del_flag = '0' limit 1
        select user_id, email
        from sys_user
        where email = #{email}
          and del_flag = '0' limit 1
    </select>
    <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
    <select id="selectAllocatedList" parameterType="com.zhitan.common.core.domain.entity.SysUser" resultMap="SysUserResult">
        select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phone_number, u.status, u.create_time
        from sys_user u
        left join sys_dept d on u.dept_id = d.dept_id
        left join sys_user_role ur on u.user_id = ur.user_id
        left join sys_role r on r.role_id = ur.role_id
        where u.del_flag = '0' and r.role_id = #{roleId}
        <if test="userName != null and userName != ''">
            AND u.user_name like concat('%', #{userName}, '%')
        </if>
        <if test="phoneNumber != null and phoneNumber != ''">
            AND u.phone_number like concat('%', #{phoneNumber}, '%')
        </if>
        <!-- æ•°æ®èŒƒå›´è¿‡æ»¤ -->
        ${params.dataScope}
    </select>
    <select id="selectUnallocatedList" parameterType="com.zhitan.common.core.domain.entity.SysUser" resultMap="SysUserResult">
        select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phone_number, u.status, u.create_time
        from sys_user u
        left join sys_dept d on u.dept_id = d.dept_id
        left join sys_user_role ur on u.user_id = ur.user_id
        left join sys_role r on r.role_id = ur.role_id
        where u.del_flag = '0' and (r.role_id != #{roleId} or r.role_id IS NULL)
        and u.user_id not in (select u.user_id from sys_user u inner join sys_user_role ur on u.user_id = ur.user_id and
        ur.role_id = #{roleId})
        <if test="userName != null and userName != ''">
            AND u.user_name like concat('%', #{userName}, '%')
        </if>
        <if test="phoneNumber != null and phoneNumber != ''">
            AND u.phone_number like concat('%', #{phoneNumber}, '%')
        </if>
        <!-- æ•°æ®èŒƒå›´è¿‡æ»¤ -->
        ${params.dataScope}
    </select>
    <insert id="insertUser" parameterType="com.zhitan.common.core.domain.entity.SysUser" useGeneratedKeys="true" keyProperty="userId">
        insert into sys_user(
        <if test="userId != null and userId != 0">user_id,</if>
        <if test="deptId != null and deptId != 0">dept_id,</if>
@@ -169,7 +215,7 @@
        )
    </insert>
    <update id="updateUser" parameterType="SysUser">
    <update id="updateUser" parameterType="com.zhitan.common.core.domain.entity.SysUser">
        update sys_user
        <set>
            <if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
@@ -191,19 +237,19 @@
        where user_id = #{userId}
    </update>
    <update id="updateUserStatus" parameterType="SysUser">
    <update id="updateUserStatus" parameterType="com.zhitan.common.core.domain.entity.SysUser">
        update sys_user
        set status = #{status}
        where user_id = #{userId}
    </update>
    <update id="updateUserAvatar" parameterType="SysUser">
    <update id="updateUserAvatar" parameterType="com.zhitan.common.core.domain.entity.SysUser">
        update sys_user
        set avatar = #{avatar}
        where user_name = #{userName}
    </update>
    <update id="resetUserPwd" parameterType="SysUser">
    <update id="resetUserPwd" parameterType="com.zhitan.common.core.domain.entity.SysUser">
        update sys_user
        set password = #{password}
        where user_name = #{userName}
zhitan-vue/.env.development
@@ -5,11 +5,5 @@
VITE_APP_ENV = 'development'
# ç³»ç»Ÿ/开发环境
# wangxiang
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# hangmingjun
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# weishuaishuai
# VITE_APP_BASE_API = 'https://demo-ems.zhitancloud.com'
# test
VITE_APP_BASE_API = 'http://139.159.201.118:8201'
VITE_APP_BASE_API = '/dev-api'
zhitan-vue/.gitignore
@@ -1,4 +1,4 @@
.DS_Store
*/.DS_Store
node_modules/
dist/
npm-debug.log*
@@ -6,6 +6,7 @@
yarn-error.log*
**/*.log
tests/**/coverage/
tests/e2e/reports
selenium-debug.log
zhitan-vue/package.json
@@ -1,9 +1,9 @@
{
  "name": "zhitan",
  "version": "3.8.7",
  "version": "2.5.2",
  "description": "管理系统",
  "author": "admin",
  "license": "MIT",
  "license": "Apache-2.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
zhitan-vue/public/favicon.ico
Binary files differ
zhitan-vue/src/api/buildingConsumption/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
import request from "@/utils/request"
export default {
  // åˆ†é¡¹ç”¨èƒ½åˆ†æž
  itemizedEnergyAnalysis(data) {
    return request({
      url: "/itemizedEnergyAnalysis/list",
      method: "GET",
      params: data,
    })
  },
  // æ”¯è·¯ç”¨èƒ½åˆ†æž
  branchanalysis(data) {
    return request({
      url: "/branchanalysis/list",
      method: "GET",
      params: data,
    })
  },
}
zhitan-vue/src/api/comprehensiveStatistics/comprehensive.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
import request from '@/utils/request'
//全厂综合能耗统计
export function getDataList(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/list',
    method: 'get',
    params: query
  })
}
//全厂综合能耗统计图
export function getlistChart(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/listChart',
    method: 'get',
    params: query
  })
}
export function exportList(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/export',
    method: 'get',
    params: query
  })
}
export function getEnergyList(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/getList',
    method: 'get',
    params: query
  })
}
//重点设备能耗排名
export function energyList(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/energyList',
    method: 'get',
    params: query
  })
}
//设备
export function getFacilityArchives() {
  return request({
    url: '/statisticalData/comprehensiveStatistics/getFacilityArchives',
    method: 'get'
  })
}
//重点设备
export function getPointFacility() {
  return request({
    url: '/statisticalData/comprehensiveStatistics/getPointFacility',
    method: 'get'
  })
}
export function getDeviceList(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/getDeviceList',
    method: 'get',
    params: query
  })
}
//获取模型下的能源品种
export function energyDevice(query) {
  return request({
    url: '/statisticalData/comprehensiveStatistics/energyDevice',
    method: 'get',
    params: query
  })
}
zhitan-vue/src/api/comprehensiveStatistics/dailyComprehensive/dailyComprehensive.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
import request from "@/utils/request"
//查询日报表
export function getDataList(query) {
  return request({
    url: "/comprehensive/dailyComprehensive/list",
    method: "get",
    params: query,
  })
}
export function getlistChart(query) {
  return request({
    url: "/comprehensive/dailyComprehensive/listChart",
    method: "get",
    params: query,
  })
}
// å¯¼å‡ºç»¼åˆæŠ¥è¡¨
export function exportList(query) {
  return request({
    url: "/report/dailyReport/export",
    method: "get",
    params: query,
  })
}
zhitan-vue/src/api/comprehensiveStatistics/monthlyComprehensive/monthlyComprehensive.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
import request from '@/utils/request'
//查询日报表
export function getDataList(query) {
  return request({
    url: '/comprehensive/monthlyComprehensive/list',
    method: 'get',
    params: query
  })
}
export function getlistChart(query) {
  return request({
    url: '/comprehensive/monthlyComprehensive/listChart',
    method: 'get',
    params: query
  })
}
zhitan-vue/src/api/comprehensiveStatistics/processEnergyConsumption.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
import request from '@/utils/request'
//全厂综合能耗统计
export function getDataList(query) {
  return request({
    url: '/statisticalData/processEnergyConsumption/list',
    method: 'get',
    params: query
  })
}
//全厂综合能耗统计图
export function getlistChart(query) {
  return request({
    url: '/statisticalData/processEnergyConsumption/listChart',
    method: 'get',
    params: query
  })
}
zhitan-vue/src/api/comprehensiveStatistics/yearComprehensive/yearComprehensive.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
import request from '@/utils/request'
//查询日报表
export function getDataList(query) {
  return request({
    url: '/comprehensive/yearComprehensive/list',
    method: 'get',
    params: query
  })
}
export function getlistChart(query) {
  return request({
    url: '/comprehensive/yearComprehensive/listChart',
    method: 'get',
    params: query
  })
}
zhitan-vue/src/api/cost/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
import request from "@/utils/request"
export function listEnergyCostTrend(query) {
  return request({
    url: "/energyTypeAnalysis/listEnergyCostTrend",
    method: "get",
    params: query,
  })
}
export function listEnergyCostTrendDetail(query) {
  return request({
    url: "/energyTypeAnalysis/listEnergyCostTrendDetail",
    method: "get",
    params: query,
  })
}
zhitan-vue/src/api/energyAnalysis/energyAnalysis.js
@@ -1,54 +1,78 @@
import request from '@/utils/request'
import request from "@/utils/request"
// èƒ½è€—对比分析-区域能耗分析-能耗趋势/区域能耗统计分析表-列表
// èƒ½è€—对比分析-科室能耗分析-能耗趋势/能耗统计分析表-列表
// èƒ½è€—对比分析-设备能耗分析-能耗趋势/能耗统计分析表-列表
export function listRegion(query) {
  return request({
    url: '/consumptionanalysis/getByArea',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getByArea",
    method: "get",
    params: query,
  })
}
// èƒ½è€—对比分析-科室能耗分析-能耗排名-列表
// èƒ½è€—对比分析-设备能耗分析-能耗排名-列表
export function listDepartment(query) {
  return request({
    url: '/consumptionanalysis/getByDepartment',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getByDepartment",
    method: "get",
    params: query,
  })
}
// èƒ½è€—对比分析-能耗指标考核-能耗趋势/区域能耗统计分析表
export function listIndicatorassessment(query) {
  return request({
    url: '/consumptionanalysis/getPlanAndProdCount',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getPlanAndProdCount",
    method: "get",
    params: query,
  })
}
// èƒ½è€—对比分析-综合能耗分析-综合能耗趋势/各介质能耗占比/区域能耗统计分析表-列表
export function listComprehensive(query) {
  return request({
    url: '/consumptionanalysis/getComprehensiveEnergy',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getComprehensiveEnergy",
    method: "get",
    params: query,
  })
}
// èƒ½è€—对比分析-综合能耗分析-能耗同比环比-列表
export function listYoY(query) {
  return request({
    url: '/consumptionanalysis/getYOY',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getYOY",
    method: "get",
    params: query,
  })
}
// èƒ½è€—对比分析-综合能耗分析-用能单元能耗排名-列表
export function listEnergyRanking(query) {
  return request({
    url: '/consumptionanalysis/getEnergyRanking',
    method: 'get',
    params: query
    url: "/consumptionanalysis/getEnergyRanking",
    method: "get",
    params: query,
  })
}
// statisticsAnalysis/getFlowCharts
export function getFlowCharts(query) {
  return request({
    url: "/statisticsAnalysis/getFlowCharts",
    method: "get",
    params: query,
  })
}
// å¯¹æ¯”分析同比
export function querySameCompareList(query) {
  return request({
    url: "/statisticsAnalysis/querySameCompareList",
    method: "get",
    params: query,
  })
}
// å¯¹æ¯”分析环比
export function queryLoopCompareList(query) {
  return request({
    url: "/statisticsAnalysis/queryLoopCompareList",
    method: "get",
    params: query,
  })
}
zhitan-vue/src/api/keyEquipment/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
import request from "@/utils/request"
export default {
  //  æŸ¥è¯¢æ‰€æœ‰è®¾å¤‡åˆ—表
  getFacilityArchives(data) {
    return request({
      url: "/keyEquipment/dailyKeyEquipment/getFacilityArchives",
      method: "GET",
      params: data,
    })
  },
  // æŸ¥è¯¢é‡ç‚¹è®¾å¤‡åˆ—表
  getPointFacility(data) {
    return request({
      url: "/keyEquipment/dailyKeyEquipment/getPointFacility",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—分析(日)图表
  dailyList(data) {
    return request({
      url: "/keyEquipment/dailyKeyEquipment/list",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—分析(日)图表
  dailyChart(data) {
    return request({
      url: "/keyEquipment/dailyKeyEquipment/listChart",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—统计(月)列表
  monthlyList(data) {
    return request({
      url: "/keyEquipment/MonthlyKeyEquipment/list",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—统计(月)图表
  monthlyChart(data) {
    return request({
      url: "/keyEquipment/MonthlyKeyEquipment/listChart",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—统计(年)列表
  yearList(data) {
    return request({
      url: "/keyEquipment/YearKeyEquipment/list",
      method: "GET",
      params: data,
    })
  },
  // é‡ç‚¹è®¾å¤‡èƒ½è€—统计(年)图表
  yearChart(data) {
    return request({
      url: "/keyEquipment/YearKeyEquipment/listChart",
      method: "GET",
      params: data,
    })
  },
}
zhitan-vue/src/api/powerquality/electric-power-factor/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
import request from "@/utils/request"
// èŽ·å–ç”¨èƒ½å•å…ƒä¸‹çš„æŸä¸ªç”µè¡¨çš„åŠŸçŽ‡å› æ•°æ•°æ®
export function powerFactorAnalysisDetail(params) {
  return request({
    url: "/powerFactorAnalysis/detail",
    method: "get",
    params,
  })
}
zhitan-vue/src/api/powerquality/electricThreePhase/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
import request from "@/utils/request"
// èŽ·å–ä¸‰ç›¸ä¸å¹³è¡¡åˆ†æžæ•°æ®
export function threePhaseUnbalanceAnalysisDetail(params) {
  return request({
    url: "/threePhaseUnbalanceAnalysis/detail",
    method: "get",
    params,
  })
}
zhitan-vue/src/api/powerquality/load-analysis/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
import request from "@/utils/request"
// èŽ·å–ç”¨èƒ½å•å…ƒä¸‹çš„ç”µè¡¨åˆ—è¡¨
export function listElectricityMeter(params) {
  return request({
    url: "/meter/listElectricityMeter",
    method: "get",
    params,
  })
}
// èŽ·å–ç”¨èƒ½å•å…ƒä¸‹çš„æŸä¸ªç”µè¡¨çš„è´Ÿè·åˆ†æžæ•°æ®
export function loadAnalysisDetail(params) {
  return request({
    url: "/loadAnalysis/detail",
    method: "get",
    params,
  })
}
// èŽ·å–ç”¨èƒ½å•å…ƒä¸‹çš„ç”µè¡¨åˆ—è¡¨-实体表
export function listElectricityDeviceMeter(params) {
  return request({
    url: "/loadAnalysis/listElectricMeter",
    method: "get",
    params,
  })
}
zhitan-vue/src/api/process/api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
import request from "@/utils/request"
export default {
  // å·¥åºèƒ½è€—分析(日)图表
  dailyList(data) {
    return request({
      url: "/processEnergy/dailyProcessEnergy/list",
      method: "GET",
      params: data,
    })
  },
  // å·¥åºèƒ½è€—分析(日)图表
  dailyChart(data) {
    return request({
      url: "/processEnergy/dailyProcessEnergy/listChart",
      method: "GET",
      params: data,
    })
  },
  // å·¥åºèƒ½è€—统计(月)列表
  monthlyList(data) {
    return request({
      url: "/processEnergy/monthlyProcessEnergy/list",
      method: "GET",
      params: data,
    })
  },
  // å·¥åºèƒ½è€—统计(月)图表
  monthlyChart(data) {
    return request({
      url: "/processEnergy/monthlyProcessEnergy/listChart",
      method: "GET",
      params: data,
    })
  },
  // å·¥åºèƒ½è€—统计(年)列表
  yearList(data) {
    return request({
      url: "/processEnergy/YearProcessEnergy/list",
      method: "GET",
      params: data,
    })
  },
  // å·¥åºèƒ½è€—统计(年)图表
  yearChart(data) {
    return request({
      url: "/processEnergy/YearProcessEnergy/listChart",
      method: "GET",
      params: data,
    })
  },
}
zhitan-vue/src/api/realTimeMonitor/historyDataTrend.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
import request from "@/utils/request"
export function getHistoricalDataByIndexId(query) {
  return request({
    url: "/dataMonitoring/historyDataTrend/getHistoricalDataByIndexId",
    method: "get",
    params: query,
  })
}
export function getEnergyIndexByModelId(query) {
  return request({
    url: "/basicsetting/model/getEnergyIndexByModelId",
    method: "get",
    params: query,
  })
}
zhitan-vue/src/assets/icons/svg/ai.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16z"></path><path d="M12 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm-4 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"></path></svg>
zhitan-vue/src/assets/icons/svg/bell.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
zhitan-vue/src/assets/images/2.png
zhitan-vue/src/assets/images/3.png
zhitan-vue/src/assets/images/5.png
zhitan-vue/src/assets/images/6.png
zhitan-vue/src/assets/images/7.png
zhitan-vue/src/assets/images/alarm.png
zhitan-vue/src/assets/images/login-background.png

zhitan-vue/src/assets/images/login-background1.jpg

zhitan-vue/src/assets/images/login-bg.jpg
Binary files differ
zhitan-vue/src/assets/images/robot.png
zhitan-vue/src/assets/styles/index.scss
@@ -9,10 +9,12 @@
body {
  height: 100%;
  margin: 0;
  padding: 0;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
  overflow-x: hidden; /* é˜²æ­¢æ°´å¹³æ»šåŠ¨æ¡ */
}
label {
@@ -22,10 +24,17 @@
html {
  height: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  overflow-x: hidden; /* é˜²æ­¢æ°´å¹³æ»šåŠ¨æ¡ */
}
#app {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  overflow-x: hidden; /* é˜²æ­¢æ°´å¹³æ»šåŠ¨æ¡ */
}
*,
@@ -135,7 +144,8 @@
//main-container全局样式
.app-container {
  padding: 20px;
  // padding: 0 12px;
  padding-right: 12px;
}
.components-container {
@@ -205,3 +215,40 @@
    color: #999 !important;
  }
}
/* æŠ˜å èœå•样式调整,确保在所有情况下菜单项居中 */
.el-menu--collapse {
  width: 54px !important;
  .el-sub-menu, .el-menu-item {
    width: 36px !important;
    min-width: 36px !important;
    margin-left: 9px !important; /* å…³é”®ï¼šè®¾ç½®å›ºå®šçš„左边距9px使菜单项居中 */
    margin-right: 9px !important;
  }
  .el-menu-item, .el-sub-menu__title {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    padding: 0 !important;
    .svg-icon, .el-icon {
      margin: 0 !important; /* é‡è¦ï¼šç§»é™¤å›¾æ ‡çš„æ‰€æœ‰è¾¹è· */
    }
    .el-sub-menu__icon-arrow {
      display: none !important;
    }
    > span {
      display: none !important;
    }
  }
  /* é€‰ä¸­çŠ¶æ€æ ·å¼ */
  .el-menu-item.is-active, .el-sub-menu.is-active > .el-sub-menu__title {
    background-color: #3883FA !important;
    color: #fff !important;
  }
}
zhitan-vue/src/assets/styles/menu-fix.scss
zhitan-vue/src/assets/styles/page.scss
@@ -4,10 +4,35 @@
      display: flex;
      .page-container-left {
        width: 280px;
        width: 220px;
        min-height: calc(100vh - 148px);
        border-right: 1px solid #1a235d;
        background: #1F1C49;
        background: #08234F;
        .el-tree {
          &.el-tree--highlight-current,
          &:not(.el-tree--highlight-current) {
            .el-tree-node {
              .el-tree-node__content {
                .el-tree-node__label,
                span {
                  font-size: 14px !important;
                }
              }
              .el-tree-node__expand-icon {
                font-size: 14px !important;
              }
            }
          }
        }
        .tree-container, .tree {
          .el-tree-node__label,
          .el-tree-node__content span {
            font-size: 14px !important;
          }
        }
        .tree {
          height: calc(100vh - 170px);
@@ -26,13 +51,68 @@
    }
    .form-card {
      background: #1a235d;
      border-radius: 0px 0px 0px 0px;
      border: 1px solid #000000;
      padding: 18px 0 0 15px;
      background: #08234F;
      border-radius: 0px;
      height: 52px;
      line-height: 52px;
      margin: 0 16px;
      display: flex;
      align-items: center;
      .el-form.el-form--inline {
        margin-left: 10px;
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
        width: 100%;
        .el-form-item {
          margin-right: 15px;
          margin-bottom: 0;
          height: 32px;
          display: flex;
          align-items: center;
          &.is-required {
            .el-form-item__label::before {
              vertical-align: middle;
            }
          }
          .el-form-item__label {
            height: 32px;
            line-height: 32px;
            color: #ffffff;
          }
          .el-form-item__content {
            display: flex;
            align-items: center;
            height: 32px;
            line-height: 32px;
            .el-input, .el-select, .el-date-editor {
              height: 32px;
              line-height: 32px;
            }
            .el-input__wrapper {
              height: 32px;
            }
            .el-button {
              height: 32px;
              line-height: 32px;
              padding-top: 0;
              padding-bottom: 0;
            }
          }
        }
      }
    }
    .table-bg-style {
      margin-top: 12px;
      .theme-dark-mt20 {
        margin-top: 20px;
      }
@@ -48,6 +128,7 @@
  .chart-box {
    width: 100%;
    height: 320px;
    padding-top: 12px;
    div {
      width: 100%;
@@ -56,7 +137,7 @@
  }
  .table-box {
    margin: 20px;
    margin: 0;
    .table-title-box {
      font-weight: bold;
@@ -82,15 +163,39 @@
      display: flex;
      .page-container-left {
        width: 280px;
        width: 220px;
        min-height: calc(100vh - 148px);
        border-right: 1px solid #fff;
        border-right: 1px solid #e8e8e8;
        background: #f1f4fa;
        // border-right: 1px solid #1a235d;
        .el-tree {
          &.el-tree--highlight-current,
          &:not(.el-tree--highlight-current) {
            .el-tree-node {
              .el-tree-node__content {
                .el-tree-node__label,
                span {
                  font-size: 14px !important;
                }
              }
              .el-tree-node__expand-icon {
                font-size: 14px !important;
              }
            }
          }
        }
        .tree-container, .tree {
          .el-tree-node__label,
          .el-tree-node__content span {
            font-size: 14px !important;
          }
        }
        .tree {
          height: calc(100vh - 170px) !important;
          max-height: calc(100vh - 170px) !important;
          height: calc(100vh - 170px);
          max-height: calc(100vh - 170px);
          overflow-y: auto;
        }
      }
@@ -106,10 +211,58 @@
    .form-card {
      background: #fff;
      border-radius: 0px 0px 0px 0px;
      // border: 1px solid #000000;
      padding: 18px 0 0 15px;
      border-radius: 0px;
      height: 52px;
      line-height: 52px;
      margin: 0 16px;
      display: flex;
      align-items: center;
      .el-form.el-form--inline {
        margin-left: 10px;
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
        width: 100%;
        .el-form-item {
          margin-right: 15px;
          margin-bottom: 0;
          height: 32px;
          display: flex;
          align-items: center;
          .el-form-item__label {
            height: 32px;
            line-height: 32px;
    }
          .el-form-item__content {
            display: flex;
            align-items: center;
            height: 32px;
            line-height: 32px;
            .el-input, .el-select, .el-date-editor {
              height: 32px;
              line-height: 32px;
            }
            .el-input__wrapper {
              height: 32px;
            }
            .el-button {
              height: 32px;
              line-height: 32px;
              padding-top: 0;
              padding-bottom: 0;
            }
          }
        }
      }
    }
    .table-bg-style {
      background-color: #fff;
      padding-top: 12px;
@@ -126,6 +279,7 @@
  .chart-box {
    width: 100%;
    height: 320px;
    padding-top: 12px;
    div {
      width: 100%;
@@ -134,7 +288,7 @@
  }
  .table-box {
    margin: 20px;
    margin: 10px 20px;
    .table-title-box {
      font-weight: bold;
@@ -154,6 +308,15 @@
}
// åˆ é™¤ä¹‹å‰æ·»åŠ çš„å…¨å±€æ ·å¼è¦†ç›–ï¼Œé¿å…å½±å“å…¨å±€
// ä¿ç•™è°ƒè¯•建议
/*
您可以在浏览器中使用以下内联样式进行调试:
document.querySelectorAll('.page-container-left .el-tree-node__label').forEach(el => {
  el.style.cssText = 'font-size: 14px !important';
});
*/
.padding {
  padding: 15px;
}
zhitan-vue/src/assets/styles/ruoyi.scss
@@ -269,14 +269,11 @@
      td {
        word-break: break-word;
        background-color: #1d3778 !important;
        // color: #515a6e;
        color: #515a6e;
        height: 48px !important;
        // font-size: 13px;
        border-radius: 0px 0px 0px 0px;
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        // font-size: 16px;
        color: #ffffff;
        border-bottom: none !important;
      }
@@ -312,6 +309,10 @@
      // tr:hover > td {
      //     background-color: #141E4A;
      // }
      .el-table-fixed-column--left {
        background-color: #110f2e !important;
      }
    }
  }
@@ -393,7 +394,7 @@
  // æ ‘
  .el-tree {
    background: transparent;
    font-size: 16px;
    font-size: 14px;
    color: #ffffff;
    .el-tree-node__content {
@@ -564,6 +565,19 @@
  }
  .el-tabs__item.is-active {
    color: #409EFF;
  }
  .el-descriptions__cell {
    background: transparent;
    color: #fff !important;
  }
  .el-descriptions__body {
    background-color: transparent;
    color: #fff;
  }
  .el-descriptions__label {
    color: #fff !important;
    background-color: #1a235d !important;
  }
}
@@ -816,14 +830,11 @@
        background-color: #F7F8FA !important;
        // color: #515a6e;
        height: 48px !important;
        // font-size: 13px;
        border-radius: 0px 0px 0px 0px;
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        // font-size: 16px;
        color: #222222;
        border-bottom: none !important;
        // border-bottom: none !important;
      }
    }
@@ -858,6 +869,9 @@
      // tr:hover > td {
      //     background-color: #141E4A;
      // }
      .el-table-fixed-column--left {
        background-color: #fff;
      }
    }
  }
@@ -869,7 +883,7 @@
  // è¡¨æ ¼åº•部白线
  .el-table__inner-wrapper::before {
    background-color: transparent;
    // background-color: transparent;
  }
  /** è¡¨å•布局 **/
zhitan-vue/src/assets/styles/sidebar.scss
@@ -1,7 +1,7 @@
.themeDark {
  #app {
    .el-menu-item.is-active {
      background: #3271eb !important;
     // background: #3271eb !important;
      // border-radius: 30px 30px 30px 30px !important;
      color: #fff;
    }
@@ -13,6 +13,7 @@
    .main-container {
      background-color: #110f2e !important;
      height: 100%;
      transition: margin-left 0.28s;
      margin-left: $base-sidebar-width;
@@ -28,13 +29,14 @@
      transition: width 0.28s;
      width: $base-sidebar-width !important;
      background-color: $base-menu-background;
      height: 100%;
      height: calc(100% - 60px) !important;
      position: fixed;
      top: 0;
      top: 60px;
      bottom: 0;
      left: 0;
      z-index: 1001;
      z-index: 999;
      overflow: hidden;
      background-color: #002866 !important;
      -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
      box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
      font-family: OPPOSans, OPPOSans;
@@ -50,10 +52,11 @@
      .scrollbar-wrapper {
        overflow-x: hidden !important;
        height: calc(100% - 290px) !important;
      }
      .el-scrollbar__bar.is-vertical {
        right: 0px;
        right: 0 !important;
      }
      .el-scrollbar {
@@ -78,6 +81,7 @@
      .svg-icon {
        margin-right: 16px;
        font-size: 14px;
      }
      .el-menu {
@@ -91,7 +95,7 @@
      .menu-title {
        overflow: hidden !important;
        font-weight: 400 !important;
        font-size: 16px !important;
        font-size: 14px !important;
      }
      // @media (min-width: 1440px) {
@@ -124,12 +128,13 @@
      .sub-menu-title-noDropdown,
      .el-sub-menu__title {
        &:hover {
          background-color: rgba(0, 0, 0, 0.06) !important;
          background-color: rgba(0, 0, 0, 0.2) !important;
        }
      }
      & .theme-dark .is-active > .el-sub-menu__title {
        color: $base-menu-color-active !important;
        background-color: rgba(0, 0, 0, 0.2) !important;
      }
      & .nest-menu .el-sub-menu > .el-sub-menu__title,
@@ -189,22 +194,32 @@
      }
      .el-menu--collapse {
        .el-sub-menu {
          & > .el-sub-menu__title {
            & > span {
              height: 0;
              width: 0;
              overflow: hidden;
              visibility: hidden;
              display: inline-block;
        width: 54px !important;
        /* æ¸…除后代选择器中干扰居中的样式 */
        .el-sub-menu, .el-menu-item {
          margin: 0 !important;
          padding: 0 !important;
          width: 100% !important;
          /* è®©å›¾æ ‡å’Œèœå•项居中 */
          .el-menu-item, .el-sub-menu__title {
            width: 36px !important;
            min-width: 36px !important;
            height: 38px !important;
            line-height: 38px !important;
            margin: 4px 9px !important; /* ç²¾ç¡®è®¡ç®—居中边距 */
            padding: 0 !important;
            display: flex !important;
            justify-content: center !important;
            align-items: center !important;
            border-radius: 4px !important;
            }
            & > i {
              height: 0;
              width: 0;
              overflow: hidden;
              visibility: hidden;
              display: inline-block;
            }
          /* ç¡®ä¿å›¾æ ‡å±…中 */
          .svg-icon, .el-icon {
            margin: 0 !important;
            padding: 0 !important;
          }
        }
      }
@@ -282,7 +297,7 @@
.themeLight {
  #app {
    .el-menu-item.is-active {
      background: #e0eafc !important;
      // border-radius: 30px 30px 30px 30px !important;
    }
@@ -292,6 +307,7 @@
    }
    .main-container {
      background-color: #f7f8fa;
      height: 100%;
      transition: margin-left 0.28s;
      margin-left: $base-sidebar-width;
@@ -307,12 +323,12 @@
      transition: width 0.28s;
      width: $base-sidebar-width !important;
      background-color: $base-menu-background;
      height: 100%;
      height: calc(100% - 60px) !important;
      position: fixed;
      top: 0;
      top: 60px;
      bottom: 0;
      left: 0;
      z-index: 1001;
      z-index: 999;
      overflow: hidden;
      -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
      box-shadow: none;
@@ -360,7 +376,7 @@
      .svg-icon {
        margin-right: 16px;
        font-size: 16px;
        font-size: 14px;
        color: #C3C3C3;
      }
@@ -375,7 +391,7 @@
      .menu-title {
        overflow: hidden !important;
        font-weight: 400 !important;
        font-size: 16px !important;
        font-size: 14px !important;
      }
      // @media (min-width: 1440px) {
@@ -412,8 +428,10 @@
        }
      }
      & .theme-dark .is-active > .el-sub-menu__title {
        // color: $base-menu-color-active !important;
      & .theme-light .is-active > .el-sub-menu__title {
        color: $--color-primary !important;
        // background-color: #eaeff8 !important;
      }
      & .nest-menu .el-sub-menu > .el-sub-menu__title,
@@ -474,22 +492,32 @@
      }
      .el-menu--collapse {
        .el-sub-menu {
          & > .el-sub-menu__title {
            & > span {
              height: 0;
              width: 0;
              overflow: hidden;
              visibility: hidden;
              display: inline-block;
        width: 54px !important;
        /* æ¸…除后代选择器中干扰居中的样式 */
        .el-sub-menu, .el-menu-item {
          margin: 0 !important;
          padding: 0 !important;
          width: 100% !important;
          /* è®©å›¾æ ‡å’Œèœå•项居中 */
          .el-menu-item, .el-sub-menu__title {
            width: 36px !important;
            min-width: 36px !important;
            height: 38px !important;
            line-height: 38px !important;
            margin: 4px 9px !important; /* ç²¾ç¡®è®¡ç®—居中边距 */
            padding: 0 !important;
            display: flex !important;
            justify-content: center !important;
            align-items: center !important;
            border-radius: 4px !important;
            }
            & > i {
              height: 0;
              width: 0;
              overflow: hidden;
              visibility: hidden;
              display: inline-block;
            }
          /* ç¡®ä¿å›¾æ ‡å±…中 */
          .svg-icon, .el-icon {
            margin: 0 !important;
            padding: 0 !important;
          }
        }
      }
zhitan-vue/src/assets/styles/variables.module.scss
@@ -42,7 +42,7 @@
$--color-danger: #F56C6C;
$--color-info: #909399;
$base-sidebar-width: 260px;
$base-sidebar-width: 220px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
zhitan-vue/src/components/Avatar/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
<template>
  <div class="avatar-container">
    <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
      <div class="avatar-wrapper">
        <img :src="userStore.avatar" class="user-avatar" />
        <el-icon><caret-bottom /></el-icon>
      </div>
      <template #dropdown>
        <el-dropdown-menu>
          <router-link to="/user/profile">
            <el-dropdown-item>个人中心</el-dropdown-item>
          </router-link>
          <el-dropdown-item command="toggleTheme">
            <span>风格切换</span>
          </el-dropdown-item>
          <el-dropdown-item divided command="logout">
            <span>退出登录</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
  </div>
</template>
<script setup>
import { ElMessageBox } from "element-plus"
import useUserStore from "@/store/modules/user"
import useSettingsStore from "@/store/modules/settings"
const userStore = useUserStore()
const settingsStore = useSettingsStore()
function handleCommand(command) {
  switch (command) {
    case "toggleTheme":
      const newTheme = settingsStore.sideTheme === "theme-dark" ? "theme-light" : "theme-dark";
      settingsStore.changeSetting({ key: "sideTheme", value: newTheme });
      document.querySelector("body").className = newTheme === "theme-dark" ? "themeDark" : "themeLight";
      break;
    case "logout":
      ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          userStore.logOut().then(() => {
            location.href = "/index";
          });
        })
        .catch(() => {});
      break;
  }
}
</script>
<style lang="scss" scoped>
.avatar-container {
  margin-right: 20px;
  .avatar-wrapper {
    margin-top: 5px;
    position: relative;
    display: flex;
    align-items: center;
    .user-avatar {
      cursor: pointer;
      width: 40px;
      height: 40px;
      border-radius: 10px;
    }
    .el-icon {
      cursor: pointer;
      margin-left: 8px;
      font-size: 12px;
      color: #ffffff;
    }
  }
}
.right-menu-item {
  display: inline-block;
  padding: 0 8px;
  height: 100%;
  font-size: 18px;
  color: #ffffff;
  vertical-align: text-bottom;
  &.hover-effect {
    cursor: pointer;
    transition: background 0.3s;
    &:hover {
      background: rgba(0, 0, 0, 0.1);
    }
  }
}
</style>
zhitan-vue/src/components/BaseCard/BaseCard.vue
@@ -5,8 +5,13 @@
    </div>
    <div class="mycard-content">
      <div class="data-box" v-if="props.tabArray.length > 0">
        <div v-for="(item, i) in props.tabArray" :key="i" class="li-box" :class="isActive == item.value ? 'is-li' : ''"
          @click="changeActive(item.value)">
        <div
          v-for="(item, i) in props.tabArray"
          :key="i"
          class="li-box"
          :class="isActive == item.value ? 'is-li' : ''"
          @click="changeActive(item.value)"
        >
          {{ item.label }}
        </div>
      </div>
@@ -16,7 +21,7 @@
</template>
<script setup>
const emit = defineEmits();
const emit = defineEmits()
const props = defineProps({
  title: {
    type: String,
@@ -30,16 +35,16 @@
    type: Array,
    default: () => [],
  },
});
})
const data = reactive({
  isActive: "DAY",
});
const { isActive } = toRefs(data);
changeActive(isActive.value);
})
const { isActive } = toRefs(data)
changeActive(isActive.value)
function changeActive(value) {
  isActive.value = value;
  emit("changeActive", isActive.value);
  isActive.value = value
  emit("changeActive", isActive.value)
}
</script>
@@ -55,19 +60,33 @@
    align-items: center;
    height: 3.7037vh; //40
    padding-left: 2.1354vw; //41px;
    background: url('../../assets/images/basecard/title_bg.png') no-repeat;
    background: url("../../assets/images/basecard/title_bg.png") no-repeat;
    background-size: auto 100%;
    .name {
      font-family: YouSheBiaoTiHei;
      font-size: 1.2500vw; //24px;
      font-size: 1.25vw; //24px;
      color: #fff;
      position: relative;
      padding-left: 12px;
      &::before {
        content: '';
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 5px;
        height: 18px;
        background-color: #3883FA;
        border-radius: 2px;
      }
    }
  }
  .mycard-content {
    border: 1px solid;
    border-image: linear-gradient(0deg, #0A3C86, #000) 1;
    border-image: linear-gradient(0deg, #0a3c86, #000) 1;
    background: linear-gradient(0deg, rgba(18, 111, 216, 0.2) 0%, rgba(18, 111, 216, 0) 100%);
    position: relative;
@@ -82,7 +101,7 @@
      z-index: 1;
      .li-box {
        border: 1px solid #2E86EA;
        border: 1px solid #2e86ea;
        cursor: pointer;
        text-align: center;
        padding: 0.3704vh 0.3125vw;
@@ -90,8 +109,8 @@
      }
      .is-li {
        background: #2E86EA;
        border: 1px solid #2E86EA;
        background: #2e86ea;
        border: 1px solid #2e86ea;
      }
    }
  }
zhitan-vue/src/components/BaseCard/index.vue
@@ -8,8 +8,7 @@
</template>
<script setup>
defineProps(['title'])
defineProps(["title"])
</script>
<style lang="scss" scoped>
@@ -29,11 +28,26 @@
      border-radius: 7px 7px 0 0;
      padding: 20px;
      background-color: #22408c;
      .name {
        font-family: OPPOSans, OPPOSans;
        font-weight: bold;
        font-size: 18px;
        color: #fff;
        position: relative;
        padding-left: 12px;
        &::before {
          content: '';
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
          width: 5px;
          height: 18px;
          background-color: #3883FA;
          border-radius: 2px;
        }
      }
    }
  }
@@ -47,6 +61,7 @@
    border: 1px solid #ebebeb;
    padding-bottom: 10px;
    background-color: #fff;
    .mycard-title {
      display: flex;
      justify-content: flex-start;
@@ -55,11 +70,26 @@
      border-radius: 7px 7px 0 0;
      padding: 20px;
      background-color: #e7eefd;
      .name {
        font-family: OPPOSans, OPPOSans;
        font-weight: bold;
        font-size: 18px;
        color: #2d2e31;
        position: relative;
        padding-left: 12px;
        &::before {
          content: '';
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
          width: 5px;
          height: 18px;
          background-color: #3883FA;
          border-radius: 2px;
        }
      }
    }
  }
zhitan-vue/src/components/Breadcrumb/index.vue
@@ -18,20 +18,30 @@
  // only show routes with meta.title
  let matched = route.matched.filter(item => item.meta && item.meta.title);
  const first = matched[0]
  // åˆ¤æ–­æ˜¯å¦ä¸ºé¦–页
  if (!isDashboard(first)) {
    matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
  // æ·»åŠ è°ƒè¯•æ—¥å¿—
  console.log('Current route path:', route.path);
  console.log('Route matched:', route.matched);
  console.log('Filtered matched routes:', matched);
  // å¦‚果是首页看板路由,确保它被添加到面包屑中
  if (route.path === '/index' || route.path === '/index/index') {
    matched = [{ path: '/index', meta: { title: '首页看板' } }].concat(matched)
    console.log('Added index route to matched:', matched);
  }
  levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
  console.log('Final breadcrumb items:', levelList.value);
}
function isDashboard(route) {
  const name = route && route.name
  if (!name) {
    return false
  }
  return name.trim() === 'Index'
  return name.trim().toLowerCase() === 'index'
}
function handleLink(item) {
  const { redirect, path } = item
  if (redirect) {
zhitan-vue/src/components/Echarts/LineChart.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,183 @@
<template>
  <div class="chart-item">
    <div :id="domId" style="width: 100%; height: 100%"></div>
  </div>
</template>
<script setup>
import * as echarts from "echarts"
const { proxy } = getCurrentInstance()
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
const emit = defineEmits()
const props = defineProps({
  chartData: {
    type: Object,
    default: () => {},
  },
  chartType: {
    type: String,
    default: "line", // bar
  },
  domId: {
    type: String,
    default: "ChartDom",
  },
})
watch(
  () => props.chartData,
  (val) => {
    console.log("watch", val)
    initChart()
  }
)
watch(
  () => settingsStore.sideTheme,
  (val) => {
    initChart()
  }
)
onMounted(() => {
  initChart()
})
function initChart(value) {
  console.log("initChart", props.chartData)
  if (!props.chartData.xAxis) {
    return
  }
  const chartDom = document.getElementById(props.domId)
  if (echarts.getInstanceByDom(chartDom)) {
    echarts.dispose(chartDom)
  }
  const myChart = echarts.init(chartDom)
  // å¤„理多系列数据
  const series = props.chartData.series.map((item) => ({
    ...item,
    name: item.name,
    type: props.chartType, // æ ¹æ®ä¼ å…¥ç±»åž‹æ¸²æŸ“
    data: item.data,
    barWidth: props.chartData.barWidth || "16",
    itemStyle: {
      borderRadius: [15, 15, 0, 0],
    },
    smooth: true, // å¯ç”¨å¹³æ»‘曲线
  }))
  console.log("initChart", series)
  let option = {
    title: {
      text: props.chartData.title || "",
      left: "40",
      textStyle: {
        color: "#2979ff",
      },
    },
    color: ["#4dadf8", "#19be6b", "#ff9900", "#3d8a32", "#e8463a", "#ff4e3f"],
    // color: ["#2979ff", "#19be6b", "#ff9900", "#fa3534"],
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    legend: {
      data: props.chartData.series.map((item) => item.name), // å›¾ä¾‹æ•°æ®
      icon: "rect",
      right: 40,
      itemWidth: 14,
      itemHeight: 10,
      textStyle: {
        color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
      },
    },
    grid: {
      top: "40",
      left: "40",
      right: "40",
      bottom: "20",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      axisPointer: {
        type: "shadow",
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
        },
      },
      axisTick: {
        show: false,
      },
      splitArea: {
        show: false,
      },
      splitLine: {
        show: false,
      },
      axisLabel: {
        color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
        fontSize: 14,
        padding: [5, 0, 0, 0],
        //   formatter: '{value} ml'
      },
      data: props.chartData.xAxis,
    },
    yAxis: [
      {
        type: "value",
        nameTextStyle: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          fontSize: 14,
          padding: [0, 0, 5, 0],
        },
        axisLine: {
          show: false,
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: "dashed",
            color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          },
        },
        axisTick: {
          show: false,
        },
        splitArea: {
          show: false,
        },
        axisLabel: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          fontSize: 14,
        },
      },
    ],
    series: series,
  }
  setTimeout(() => {
    myChart.setOption(option)
  }, 200)
  window.addEventListener(
    "resize",
    () => {
      myChart.resize()
    },
    { passive: true }
  )
}
</script>
<style lang="scss" scoped>
.chart-item {
  width: 100%;
  height: 360px !important;
  margin-top: 0px;
  padding-top: 20px;
}
</style>
zhitan-vue/src/components/Hamburger/index.vue
@@ -12,7 +12,7 @@
    </svg> -->
    
    <img src="/src/assets/images/nav-btn.png" width="26" v-if="settingsStore.sideTheme == 'theme-dark'">
    <img src="/src/assets/images/nav-btn2.png" width="26" v-else>
    <img src="/src/assets/images/nav-btn.png" width="26" v-else>
  </div>
</template>
zhitan-vue/src/components/HeaderSearch/index.vue
@@ -52,7 +52,7 @@
    window.open(path.substr(pindex, path.length), "_blank");
  } else {
    if (query) {
      router.push({ path: path, query: JSON.parse(query) });
      router.push({ path: path, query: query });
    } else {
      router.push(path)
    }
zhitan-vue/src/components/LeftTree/index.vue
@@ -53,14 +53,26 @@
getTree();
/** æŸ¥è¯¢éƒ¨é—¨ä¸‹æ‹‰æ ‘结构 */
function getTree() {
  // ç¡®ä¿query.value有初始值
  query.value = query.value || {};
  // ä¼˜å…ˆä½¿ç”¨props中传入的ParentModelCode
  if (props.ParentModelCode) {
    query.value = { modelCode: props.ParentModelCode };
    query.value.modelCode = props.ParentModelCode;
  } else if (useRoute().query.modelCode) {
    // å…¶æ¬¡ä½¿ç”¨è·¯ç”±ä¸­çš„modelCode
    query.value.modelCode = useRoute().query.modelCode;
  } else {
    query.value = { ...useRoute().query };
    // æœ€åŽä½¿ç”¨é»˜è®¤å€¼
    query.value.modelCode = 'JCZBK_CODE';
  }
  console.log('LeftTree getTree modelCode:', query.value.modelCode);
  treeList(query.value).then((response) => {
    nodeOptions.value = response.data;
    if (response.data.length > 0) {
      defaultExpandedKeys.value = []; // æ¸…空已有的key,避免重复
      response.data.map((item) => {
        defaultExpandedKeys.value.push(item.id);
      });
zhitan-vue/src/components/TagsView/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
function isTags(route) {
  return !route.hidden && route.name &&
    route.name !== 'login' &&
    route.name !== '404' &&
    route.name !== '401' &&
    route.name !== 'index' &&
    route.path !== '/index' &&
    route.path !== '/';
}
function addTags() {
  const { name } = route;
  if (name) {
    // æ£€æŸ¥æ˜¯å¦ä¸ºé¦–页
    if (name === 'index' || route.path === '/index' || route.path === '/') {
      return;
    }
    store.dispatch('tagsView/addView', route);
  }
  return false;
}
// åˆå§‹åŒ–标签,确保首页不被添加为固定标签
function initTags() {
  const affixTags = filterAffixTags(routes);
  for (const tag of affixTags) {
    // æŽ’除首页
    if (tag.path === '/index' || tag.path === '/' || tag.name === 'Index') {
      continue;
    }
    // æ·»åŠ å›ºå®šæ ‡ç­¾
    if (tag.name) {
      store.dispatch('tagsView/addVisitedView', tag);
    }
  }
}
zhitan-vue/src/components/TopNav/index.vue
@@ -1,35 +1,30 @@
<template>
  <div class="top-nav-container">
    <div class="scroll-arrow left-arrow" @click="scrollLeft" v-show="canScrollLeft">
      <el-icon><arrow-left /></el-icon>
    </div>
    <div class="menu-container" ref="menuContainer">
  <el-menu
    :default-active="activeMenu"
    mode="horizontal"
    @select="handleSelect"
    :ellipsis="false"
        class="top-menu"
        :class="{ 'theme-dark': theme === 'dark' }"
  >
    <template v-for="(item, index) in topMenus">
      <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
        <svg-icon
        v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
        :icon-class="item.meta.icon"/>
        <template v-for="(item, index) in topMenus" :key="index">
          <el-menu-item :style="{'--theme': theme}" :index="item.path">
        {{ item.meta.title }}
      </el-menu-item>
    </template>
    <!-- é¡¶éƒ¨èœå•超出数量折叠 -->
    <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
      <template #title>更多菜单</template>
      <template v-for="(item, index) in topMenus">
        <el-menu-item
          :index="item.path"
          :key="index"
          v-if="index >= visibleNumber">
        <svg-icon
          v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
          :icon-class="item.meta.icon"/>
        {{ item.meta.title }}
        </el-menu-item>
      </template>
    </el-sub-menu>
  </el-menu>
    </div>
    <div class="scroll-arrow right-arrow" @click="scrollRight" v-show="canScrollRight">
      <el-icon><arrow-right /></el-icon>
    </div>
  </div>
</template>
<script setup>
@@ -38,9 +33,13 @@
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
// é¡¶éƒ¨æ åˆå§‹æ•°
const visibleNumber = ref(null);
// æ»šåŠ¨ç›¸å…³
const menuContainer = ref(null);
const canScrollLeft = ref(false);
const canScrollRight = ref(false);
// å½“前激活菜单的 index
const currentIndex = ref(null);
// éšè—ä¾§è¾¹æ è·¯ç”±
@@ -104,6 +103,10 @@
    if (!route.meta.link) {
        appStore.toggleSideBarHide(false);
    }
  } else if (path === '/index' || path === '/') {
    // é¦–页时隐藏侧边栏
    activePath = path;
    appStore.toggleSideBarHide(true);
  } else if(!route.children) {
    activePath = path;
    appStore.toggleSideBarHide(true);
@@ -112,36 +115,147 @@
  return activePath;
})
function setVisibleNumber() {
  const width = document.body.getBoundingClientRect().width / 3;
  visibleNumber.value = parseInt(width / 85);
function updateScrollButtons() {
  if (!menuContainer.value) return;
  const container = menuContainer.value;
  canScrollLeft.value = container.scrollLeft > 10;
  canScrollRight.value = container.scrollLeft < (container.scrollWidth - container.clientWidth - 10);
}
function scrollLeft() {
  if (!menuContainer.value) return;
  menuContainer.value.scrollBy({ left: -200, behavior: 'smooth' });
  setTimeout(updateScrollButtons, 300);
}
function scrollRight() {
  if (!menuContainer.value) return;
  menuContainer.value.scrollBy({ left: 200, behavior: 'smooth' });
  setTimeout(updateScrollButtons, 300);
}
/**
 * æŸ¥æ‰¾æœ€æ·±å±‚的子菜单(叶子节点)
 * é€’归查找第一个没有children的子菜单
 */
function findDeepestLeafMenu(route) {
  if (!route) return null;
  // å¦‚果没有子菜单或子菜单为空,则返回当前路由
  if (!route.children || route.children.length === 0) {
    return route;
  }
  // æ‰¾åˆ°ç¬¬ä¸€ä¸ªéžéšè—çš„子菜单
  const firstVisibleChild = route.children.find(child => !child.hidden);
  if (!firstVisibleChild) {
    return route; // å¦‚果所有子菜单都是隐藏的,返回当前路由
  }
  // é€’归查找这个子菜单的最深层子菜单
  return findDeepestLeafMenu(firstVisibleChild);
}
function handleSelect(key, keyPath) {
  currentIndex.value = key;
  const route = routers.value.find(item => item.path === key);
  if (isHttp(key)) {
    // http(s):// è·¯å¾„新窗口打开
    window.open(key, "_blank");
  } else if (!route || !route.children) {
    // æ²¡æœ‰å­è·¯ç”±è·¯å¾„内部打开
    return;
  }
  // æ£€æŸ¥æ˜¯å¦æœ‰å­è·¯ç”±
  if (route && route.children && route.children.length > 0) {
    // æœ‰å­è·¯ç”±ï¼Œæ˜¾ç¤ºä¾§è¾¹æ 
    activeRoutes(key);
    // æŒ‰ç…§æ­£ç¡®çš„路径构建层级,这里是特殊处理
    let targetPath = key; // ä»Žå½“前点击的菜单路径开始
    let targetQuery = null;
    let currentNode = route;
    let pathSegments = [];
    // å½“前路径是第一段
    pathSegments.push(currentNode.path);
    // é€å±‚添加子路径
    while (currentNode.children && currentNode.children.length > 0) {
      const firstChild = currentNode.children.find(child => !child.hidden);
      if (!firstChild) break;
      // è·³è¿‡ParentView类型的中间节点,直接使用其子节点的path
      if (firstChild.component === 'ParentView' || firstChild.component.name === 'ParentView') {
        currentNode = firstChild;
        pathSegments.push(firstChild.path);
        continue;
      }
      // æ™®é€šèŠ‚ç‚¹å¤„ç†
      currentNode = firstChild;
      // å¦‚果路径不是以/开头,则添加到路径片段中
      if (!firstChild.path.startsWith('/')) {
        pathSegments.push(firstChild.path);
      } else {
        // å¦‚果是绝对路径,则替换之前所有路径
        pathSegments = [firstChild.path];
      }
      targetQuery = firstChild.query;
      // å¦‚果到达叶子节点(没有子节点),则结束查找
      if (!firstChild.children || firstChild.children.length === 0) {
        break;
      }
    }
    // æž„建最终路径
    if (pathSegments.length > 0) {
      // å¦‚果第一段不是以/开头,添加/
      if (!pathSegments[0].startsWith('/')) {
        pathSegments[0] = '/' + pathSegments[0];
      }
      // ç»„合路径 - æŠŠæ•°ç»„中所有路径拼接起来,如果某段包含完整路径(以/开头)则从该段重新开始
      targetPath = pathSegments.reduce((fullPath, segment, index) => {
        if (segment.startsWith('/')) {
          return segment;
        } else if (index === 0) {
          return segment;
        } else {
          return `${fullPath}/${segment}`;
        }
      });
    }
    // å¯¼èˆªåˆ°ç›®æ ‡è·¯ç”±
    if (targetQuery) {
      router.push({ path: targetPath, query: targetQuery });
    } else {
      router.push({ path: targetPath });
    }
  } else {
    // æ²¡æœ‰å­è·¯ç”±ï¼Œéšè—ä¾§è¾¹æ 
    const routeMenu = childrenMenus.value.find(item => item.path === key);
    if (routeMenu && routeMenu.query) {
      let query = JSON.parse(routeMenu.query);
      router.push({ path: key, query: query });
      // query å·²ç»åœ¨ permission.js ä¸­è¢«å¤„理为对象,无需再次解析
      router.push({ path: key, query: routeMenu.query });
    } else {
      router.push({ path: key });
    }
    appStore.toggleSideBarHide(true);
  } else {
    // æ˜¾ç¤ºå·¦ä¾§è”动菜单
    activeRoutes(key);
    appStore.toggleSideBarHide(false);
  }
}
function activeRoutes(key) {
  let routes = [];
  // æŸ¥æ‰¾åŒ¹é…çš„路由
  if (childrenMenus.value && childrenMenus.value.length > 0) {
    childrenMenus.value.map((item) => {
      if (key == item.parentPath || (key == "index" && "" == item.path)) {
@@ -149,66 +263,183 @@
      }
    });
  }
  if(routes.length > 0) {
    // æœ‰å­è·¯ç”±ï¼Œåˆ™æ˜¾ç¤ºä¾§è¾¹æ 
    permissionStore.setSidebarRouters(routes);
    appStore.toggleSideBarHide(false);
  } else {
    // æ²¡æœ‰å­è·¯ç”±ï¼Œéšè—ä¾§è¾¹æ 
    appStore.toggleSideBarHide(true);
  }
  return routes;
}
onMounted(() => {
  window.addEventListener('resize', setVisibleNumber)
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', setVisibleNumber)
  // æ ¹æ®å½“前路由决定是否显示侧边栏,而不是直接隐藏
  const currentPath = route.path;
  if (currentPath === '/index' || currentPath === '/') {
    // å¦‚果当前是首页,自动跳转到第一个动态路由
    if (topMenus.value.length > 0) {
      const firstRoute = topMenus.value[0];
      handleSelect(firstRoute.path);
    }
  } else {
    // æ£€æŸ¥å½“前路由是否需要显示侧边栏
    const routeConfig = routers.value.find(item => currentPath.startsWith(item.path) && item.path !== '/');
    if (routeConfig && routeConfig.children && routeConfig.children.length > 0) {
      // æœ‰å­èœå•,显示侧边栏
      activeRoutes(routeConfig.path);
      appStore.toggleSideBarHide(false);
    } else {
      // æ— å­èœå•,可以隐藏侧边栏
      appStore.toggleSideBarHide(true);
    }
  }
  // ç›‘听滚动状态
  if (menuContainer.value) {
    menuContainer.value.addEventListener('scroll', updateScrollButtons);
    nextTick(() => {
      updateScrollButtons();
    });
  }
  window.addEventListener('resize', () => {
    updateScrollButtons();
  });
})
onMounted(() => {
  setVisibleNumber()
onBeforeUnmount(() => {
  if (menuContainer.value) {
    menuContainer.value.removeEventListener('scroll', updateScrollButtons);
  }
  window.removeEventListener('resize', updateScrollButtons);
})
</script>
<style lang="scss">
.topmenu-container.el-menu--horizontal > .el-menu-item {
  float: left;
  height: 50px !important;
  line-height: 50px !important;
  color: #999093 !important;
  padding: 0 5px !important;
  margin: 0 10px !important;
.top-nav-container {
  display: flex;
  align-items: center;
  flex: 1;
  position: relative;
  height: 60px;
  overflow: hidden;
  padding: 0 40px; /* Increase padding for arrows */
  .scroll-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    cursor: pointer;
    color: #ffffff;
    z-index: 20;
    opacity: 0;
    transition: opacity 0.3s;
    position: absolute;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    &:hover {
      background: rgba(255, 255, 255, 0.3);
}
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title {
  border-bottom: 2px solid #{'var(--theme)'} !important;
  color: #303133;
    &.left-arrow {
      left: 8px;
}
/* sub-menu item */
.topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
  float: left;
  height: 50px !important;
  line-height: 50px !important;
  color: #999093 !important;
  padding: 0 5px !important;
  margin: 0 10px !important;
    &.right-arrow {
      right: 8px;
    }
}
/* èƒŒæ™¯è‰²éšè— */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
  background-color: #ffffff !important;
  &:hover {
    .scroll-arrow {
      opacity: 1;
    }
  }
  .menu-container {
    width: 100%;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE and Edge */
    &::-webkit-scrollbar {
      display: none; /* Chrome, Safari, Opera */
    }
  }
}
.top-menu {
  height: 60px;
  border-bottom: none !important;
  white-space: nowrap;
  background: transparent !important;
  &.theme-dark {
    background: #002866 !important;
  }
}
.el-menu--horizontal {
  border-bottom: none !important;
  > .el-menu-item {
    display: inline-block;
    float: none;
    height: 60px !important;
    line-height: 60px !important;
    color: #ffffff !important;
    padding: 0 20px !important;
    margin: 0 !important;
    border-bottom: none !important;
    position: relative;
    font-size: 16px;
    &.is-active {
      background-color: transparent !important;
      color: #ffffff !important;
      font-weight: bold;
      &::after {
        content: '';
        position: absolute;
        bottom: 10px;
        left: 50%;
        transform: translateX(-50%);
        width: calc(100% - 40px);
        height: 2px;
        background-color: #ffffff;
      }
    }
    &:hover {
      background-color: rgba(255, 255, 255, 0.1) !important;
      color: #ffffff !important;
    }
  }
}
/* å›¾æ ‡å³é—´è· */
.topmenu-container .svg-icon {
  margin-right: 4px;
.svg-icon {
  margin-right: 8px;
  color: #ffffff;
}
/* topmenu more arrow */
.topmenu-container .el-sub-menu .el-sub-menu__icon-arrow {
  position: static;
  vertical-align: middle;
  margin-left: 8px;
  margin-top: 0px;
/* é¦–页按钮样式 */
.el-menu-item:first-child {
  margin-left: 0 !important;
  font-weight: bold;
  .svg-icon {
    font-size: 18px;
  }
}
</style>
zhitan-vue/src/layout/components/AppMain.vue
@@ -27,7 +27,9 @@
    position: relative;
    overflow: hidden;
    background: #110f2e;
    padding: 14px 0 0 14px;
    padding: 14px;
    box-sizing: border-box;
    padding-top: 8px;
  }
  .fixed-header + .app-main {
@@ -37,12 +39,11 @@
  .hasTagsView {
    .app-main {
      /* 84 = navbar + tags-view + padding = 70 + 56 + 14 */
      min-height: calc(100vh - 125px);
      // padding: 20px;
      min-height: calc(100vh - 110px);
    }
    .fixed-header + .app-main {
      padding-top: 130px;
      padding-top: 108px; /* 60px(navbar) + 34px(tagsview) + 14px(内边距) */
    }
  }
}
@@ -55,7 +56,8 @@
    position: relative;
    overflow: hidden;
    background: #f7f8fa;
    padding: 14px 0 0 14px;
    padding: 14px;
    box-sizing: border-box;
  }
  .fixed-header + .app-main {
@@ -65,15 +67,19 @@
  .hasTagsView {
    .app-main {
      /* 84 = navbar + tags-view + padding = 70 + 56 + 14 */
      min-height: calc(100vh - 125px);
      // padding: 20px;
      min-height: calc(100vh - 110px);
    }
    .fixed-header + .app-main {
      padding-top: 130px;
      padding-top: 108px; /* 60px(navbar) + 34px(tagsview) + 14px(内边距) */
    }
  }
}
/* ç”¨æˆ·ä¸ªäººèµ„料页特殊高度处理 */
.user-profile-container {
  min-height: calc(100vh - 50px) !important;
}
</style>
<style lang="scss">
zhitan-vue/src/layout/components/Navbar.vue
@@ -12,108 +12,53 @@
    </div>
    <div class="right-menu">
      <!-- <template v-if="appStore.device !== 'mobile'">
        <header-search id="header-search" class="right-menu-item" />
        <screenfull id="screenfull" class="right-menu-item hover-effect" />
        <el-tooltip content="布局大小" effect="dark" placement="bottom">
          <size-select id="size-select" class="right-menu-item hover-effect" />
        </el-tooltip>
      </template> -->
      <!-- <el-button @click="toggleTheme">切换</el-button> -->
      <div class="avatar-container">
        <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
          <div class="avatar-wrapper">
            <img :src="userStore.avatar" class="user-avatar" />
            <el-icon><caret-bottom /></el-icon>
      <!-- æŠ¥è­¦æŒ‰é’® -->
      <div class="right-menu-item hover-effect nav-btn-item">
        <el-tooltip content="报警" effect="dark" placement="bottom">
          <div class="nav-btn" @click="handleAlarm">
            <img src="@/assets/images/alarm.png" alt="报警" />
            <span>报警</span>
          </div>
          <template #dropdown>
            <el-dropdown-menu>
              <router-link to="/user/profile">
                <el-dropdown-item>个人中心</el-dropdown-item>
              </router-link>
              <el-dropdown-item command="toggleTheme">
                <span>风格切换</span>
              </el-dropdown-item>
              <!--
              <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
                <span>布局设置</span>
              </el-dropdown-item> -->
              <el-dropdown-item divided command="logout">
                <span>退出登录</span>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        </el-tooltip>
      </div>
      <!-- å¤§æ¨¡åž‹æŒ‰é’® -->
      <div class="right-menu-item hover-effect nav-btn-item">
        <el-tooltip content="大模型" effect="dark" placement="bottom">
          <div class="nav-btn" @click="handleRobot">
            <img src="@/assets/images/robot.png" alt="大模型" />
            <span>大模型</span>
          </div>
        </el-tooltip>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ElMessageBox } from "element-plus"
import Breadcrumb from "@/components/Breadcrumb"
import TopNav from "@/components/TopNav"
import Hamburger from "@/components/Hamburger"
import Screenfull from "@/components/Screenfull"
import SizeSelect from "@/components/SizeSelect"
import HeaderSearch from "@/components/HeaderSearch"
import useAppStore from "@/store/modules/app"
import useUserStore from "@/store/modules/user"
import useSettingsStore from "@/store/modules/settings"
import { useRouter } from "vue-router"
const appStore = useAppStore()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
function toggleTheme() {
  if (settingsStore.sideTheme == "theme-dark") {
    settingsStore.sideTheme = "theme-light"
    document.querySelector("body").className = "themeLight"
  } else {
    settingsStore.sideTheme = "theme-dark"
    document.querySelector("body").className = "themeDark"
  }
}
const router = useRouter()
function toggleSideBar() {
  appStore.toggleSideBar()
}
function handleCommand(command) {
  switch (command) {
    case "toggleTheme":
      toggleTheme()
      break
    case "setLayout":
      setLayout()
      break
    case "logout":
      logout()
      break
    default:
      break
  }
function handleAlarm() {
  // è·³è½¬åˆ°æŠ¥è­¦ç®¡ç†é¡µé¢
  router.push('/alarmmanage/measuremen?modelCode=BJGL')
}
function logout() {
  ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      userStore.logOut().then(() => {
        location.href = "/index"
      })
    })
    .catch(() => {})
}
const emits = defineEmits(["setLayout"])
function setLayout() {
  emits("setLayout")
function handleRobot() {
  // è·³è½¬åˆ°æ™ºèƒ½åŠ©æ‰‹é¡µé¢
  window.open('https://deepseek.tan-zhonghe.com/chat', '_blank')
}
</script>
@@ -188,26 +133,35 @@
        }
      }
      .avatar-container {
        margin-right: 40px;
      .nav-btn-item {
        display: flex;
        align-items: center;
        margin-right: 20px;
        height: 70px;
        .avatar-wrapper {
          margin-top: 5px;
          position: relative;
          .user-avatar {
        .nav-btn {
          display: flex;
          align-items: center;
          justify-content: center;
            cursor: pointer;
            width: 40px;
            height: 40px;
            border-radius: 10px;
          color: #fff;
          background-color: rgba(255, 255, 255, 0.1);
          border-radius: 4px;
          padding: 8px 16px;
          &:hover {
            background-color: rgba(255, 255, 255, 0.2);
          }
          i {
            cursor: pointer;
            position: absolute;
            right: -20px;
            top: 25px;
            font-size: 12px;
          img {
            width: 20px;
            height: 20px;
            margin-right: 6px;
          }
          span {
            font-size: 14px;
            font-weight: 500;
          }
        }
      }
@@ -284,26 +238,35 @@
        }
      }
      .avatar-container {
        margin-right: 40px;
      .nav-btn-item {
        display: flex;
        align-items: center;
        margin-right: 20px;
        height: 70px;
        .avatar-wrapper {
          margin-top: 5px;
          position: relative;
          .user-avatar {
        .nav-btn {
          display: flex;
          align-items: center;
          justify-content: center;
            cursor: pointer;
            width: 40px;
            height: 40px;
            border-radius: 10px;
          color: #333;
          background-color: rgba(0, 0, 0, 0.05);
          border-radius: 4px;
          padding: 8px 16px;
          &:hover {
            background-color: rgba(0, 0, 0, 0.1);
          }
          i {
            cursor: pointer;
            position: absolute;
            right: -20px;
            top: 25px;
            font-size: 12px;
          img {
            width: 20px;
            height: 20px;
            margin-right: 6px;
          }
          span {
            font-size: 14px;
            font-weight: 500;
          }
        }
      }
zhitan-vue/src/layout/components/Settings/index.vue
@@ -6,20 +6,42 @@
    <div class="setting-drawer-block-checbox">
      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
        <img src="@/assets/images/dark.svg" alt="dark" />
        <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
        <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block">
          <i aria-label="图标: check" class="anticon anticon-check">
            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
              <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
            <svg
              viewBox="64 64 896 896"
              data-icon="check"
              width="1em"
              height="1em"
              :fill="theme"
              aria-hidden="true"
              focusable="false"
              class
            >
              <path
                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
              />
            </svg>
          </i>
        </div>
      </div>
      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
        <img src="@/assets/images/light.svg" alt="light" />
        <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
        <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block">
          <i aria-label="图标: check" class="anticon anticon-check">
            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
              <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
            <svg
              viewBox="64 64 896 896"
              data-icon="check"
              width="1em"
              height="1em"
              :fill="theme"
              aria-hidden="true"
              focusable="false"
              class
            >
              <path
                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
              />
            </svg>
          </i>
        </div>
@@ -75,66 +97,67 @@
    <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">保存配置</el-button>
    <el-button plain icon="Refresh" @click="resetSetting">重置配置</el-button>
  </el-drawer>
</template>
<script setup>
import variables from '@/assets/styles/variables.module.scss'
import axios from 'axios'
import { ElLoading, ElMessage } from 'element-plus'
import { useDynamicTitle } from '@/utils/dynamicTitle'
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import { handleThemeStyle } from '@/utils/theme'
import variables from "@/assets/styles/variables.module.scss"
import axios from "axios"
import { ElLoading, ElMessage } from "element-plus"
import { useDynamicTitle } from "@/utils/dynamicTitle"
import useAppStore from "@/store/modules/app"
import useSettingsStore from "@/store/modules/settings"
import usePermissionStore from "@/store/modules/permission"
import { handleThemeStyle } from "@/utils/theme"
const { proxy } = getCurrentInstance();
const { proxy } = getCurrentInstance()
const appStore = useAppStore()
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
const showSettings = ref(false);
const theme = ref(settingsStore.theme);
const sideTheme = ref(settingsStore.sideTheme);
const storeSettings = computed(() => settingsStore);
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]);
const showSettings = ref(false)
const theme = ref(settingsStore.theme)
const sideTheme = ref(settingsStore.sideTheme)
const storeSettings = computed(() => settingsStore)
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
/** æ˜¯å¦éœ€è¦topnav */
function topNavChange(val) {
  if (!val) {
    appStore.toggleSideBarHide(false);
    permissionStore.setSidebarRouters(permissionStore.defaultRoutes);
    appStore.toggleSideBarHide(false)
    permissionStore.setSidebarRouters(permissionStore.defaultRoutes)
  }
}
function themeChange(val) {
  settingsStore.theme = val;
  handleThemeStyle(val);
  settingsStore.theme = val
  handleThemeStyle(val)
}
function handleTheme(val) {
  settingsStore.sideTheme = val;
  sideTheme.value = val;
  settingsStore.sideTheme = val
  sideTheme.value = val
  // Update body class to match the theme
  document.querySelector("body").className = val === 'theme-dark' ? "themeDark" : "themeLight"
}
function saveSetting() {
  proxy.$modal.loading("正在保存到本地,请稍候...");
  proxy.$modal.loading("正在保存到本地,请稍候...")
  let layoutSetting = {
    "topNav": storeSettings.value.topNav,
    "tagsView": storeSettings.value.tagsView,
    "fixedHeader": storeSettings.value.fixedHeader,
    "sidebarLogo": storeSettings.value.sidebarLogo,
    "dynamicTitle": storeSettings.value.dynamicTitle,
    "sideTheme": storeSettings.value.sideTheme,
    "theme": storeSettings.value.theme
  };
  localStorage.setItem("layout-setting", JSON.stringify(layoutSetting));
    topNav: storeSettings.value.topNav,
    tagsView: storeSettings.value.tagsView,
    fixedHeader: storeSettings.value.fixedHeader,
    sidebarLogo: storeSettings.value.sidebarLogo,
    dynamicTitle: storeSettings.value.dynamicTitle,
    sideTheme: storeSettings.value.sideTheme,
    theme: storeSettings.value.theme,
  }
  localStorage.setItem("layout-setting", JSON.stringify(layoutSetting))
  setTimeout(proxy.$modal.closeLoading(), 1000)
}
function resetSetting() {
  proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...");
  proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
  localStorage.removeItem("layout-setting")
  setTimeout("window.location.reload()", 1000)
}
function openSetting() {
  showSettings.value = true;
  showSettings.value = true
}
defineExpose({
@@ -142,7 +165,7 @@
})
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.setting-drawer-title {
  margin-bottom: 12px;
  color: rgba(0, 0, 0, 0.85);
zhitan-vue/src/layout/components/Sidebar/SidebarItem.vue
@@ -9,7 +9,7 @@
      </app-link>
    </template>
    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported @click="handleSubMenuClick">
      <template v-if="item.meta" #title>
        <svg-icon :icon-class="item.meta && item.meta.icon" />
        <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
@@ -31,6 +31,9 @@
import { isExternal } from '@/utils/validate'
import AppLink from './Link'
import { getNormalPath } from '@/utils/ruoyi'
import { useRouter } from 'vue-router'
const router = useRouter();
const props = defineProps({
  // route object
@@ -50,6 +53,204 @@
const onlyOneChild = ref({});
/**
 * æŸ¥æ‰¾æœ€æ·±å±‚的子菜单(叶子节点)
 * é€’归查找第一个没有children的子菜单
 */
function findDeepestLeafMenu(route) {
  if (!route) return null;
  // å¦‚果没有子菜单或子菜单为空,则返回当前路由
  if (!route.children || route.children.length === 0) {
    return route;
  }
  // æ‰¾åˆ°ç¬¬ä¸€ä¸ªéžéšè—çš„子菜单
  const firstVisibleChild = route.children.find(child => !child.hidden);
  if (!firstVisibleChild) {
    return route; // å¦‚果所有子菜单都是隐藏的,返回当前路由
  }
  // é€’归查找这个子菜单的最深层子菜单
  return findDeepestLeafMenu(firstVisibleChild);
}
// å¤„理子菜单点击
function handleSubMenuClick(e) {
  // é˜»æ­¢äº‹ä»¶å†’泡
  e.stopPropagation();
  // å¦‚果点击的是子菜单标题,则自动导航到最深层的子菜单
  if (e.target.closest('.el-sub-menu__title')) {
    // æŒ‰ç…§æ­£ç¡®çš„路径构建层级
    let currentNode = props.item;
    console.log('当前点击的菜单项:', JSON.stringify(currentNode, null, 2));
    console.log('basePath:', props.basePath);
    // èŽ·å–ç¬¬ä¸€ä¸ªå¯è§å­èœå•ï¼Œå¦‚æžœæ²¡æœ‰å¯è§å­èœå•ï¼Œä¸è¿›è¡Œè·³è½¬
    if (!currentNode.children || currentNode.children.length === 0) {
      return;
    }
    const firstVisibleChild = currentNode.children.find(child => !child.hidden);
    if (!firstVisibleChild) {
      return;
    }
    console.log('第一个可见子菜单:', JSON.stringify(firstVisibleChild, null, 2));
    // æ—¥å¿—管理等三级菜单特殊处理
    // æ£€æŸ¥æ˜¯å¦æœ‰é¢„先写入的完整路径,如果有则直接使用
    if (firstVisibleChild.fullPath) {
      console.log('使用预先设置的完整路径:', firstVisibleChild.fullPath);
      router.push({ path: firstVisibleChild.fullPath });
      return;
    }
    // åˆ¤æ–­æ˜¯å¦æ˜¯ç³»ç»Ÿ/日志管理类型的三级菜单(例如,/system/log/operlog)
    // è¿™ç§æƒ…况下,直接跳转到第一个子菜单的完整路径
    if (firstVisibleChild.component === 'ParentView' ||
        (typeof firstVisibleChild.component === 'object' &&
         firstVisibleChild.component.name === 'ParentView')) {
      console.log('检测到ParentView组件,处理三级菜单');
      // æ˜¯æœ‰ä¸‰çº§èœå•的情况
      if (firstVisibleChild.children && firstVisibleChild.children.length > 0) {
        const grandChild = firstVisibleChild.children.find(child => !child.hidden);
        if (grandChild) {
          console.log('找到第三级菜单:', JSON.stringify(grandChild, null, 2));
          // åˆ¤æ–­æ˜¯å¦åº”该使用parentPath
          if (firstVisibleChild.parentPath && grandChild.path.startsWith('/')) {
            console.log('使用parentPath属性:', firstVisibleChild.parentPath);
            // å¦‚果子菜单是绝对路径,但有parentPath,则应该使用parentPath作为基础
            let fullPath = firstVisibleChild.parentPath;
            if (!fullPath.startsWith('/')) {
              fullPath = '/' + fullPath;
            }
            // ç¬¬äºŒçº§è·¯å¾„基于根路径
            if (firstVisibleChild.path.startsWith('/')) {
              // ç¬¬äºŒçº§å·²ç»æ˜¯ç»å¯¹è·¯å¾„,截取最后部分
              const pathParts = firstVisibleChild.path.split('/');
              const lastPart = pathParts[pathParts.length - 1];
              fullPath = fullPath + '/' + lastPart;
            } else {
              fullPath = buildFullPath(fullPath, firstVisibleChild.path);
            }
            console.log('二级路径:', fullPath);
            // ç¬¬ä¸‰çº§è·¯å¾„基于二级路径
            if (grandChild.path.startsWith('/')) {
              // ç¬¬ä¸‰çº§æ˜¯ç»å¯¹è·¯å¾„,截取最后部分
              const pathParts = grandChild.path.split('/');
              const lastPart = pathParts[pathParts.length - 1];
              fullPath = fullPath + '/' + lastPart;
            } else {
              fullPath = buildFullPath(fullPath, grandChild.path);
            }
            console.log('三级路径 (最终):', fullPath);
            // å¯¼èˆªåˆ°ç¬¬ä¸‰çº§èœå•
            if (grandChild.query) {
              router.push({ path: fullPath, query: grandChild.query });
            } else {
              router.push({ path: fullPath });
            }
            return;
          }
          // å¸¸è§„路径构建
          let fullPath;
          // ç¬¬ä¸€çº§è·¯å¾„必须是完整的(例如/system)
          if (currentNode.path.startsWith('/')) {
            fullPath = currentNode.path;
          } else {
            fullPath = '/' + currentNode.path;
          }
          console.log('一级路径:', fullPath);
          // ç¬¬äºŒçº§è·¯å¾„必须基于第一级路径(例如/system/log)
          fullPath = buildFullPath(fullPath, firstVisibleChild.path);
          console.log('二级路径:', fullPath);
          // ç¬¬ä¸‰çº§è·¯å¾„必须基于二级路径(例如/system/log/operlog)
          fullPath = buildFullPath(fullPath, grandChild.path);
          console.log('三级路径 (最终):', fullPath);
          // å¯¼èˆªåˆ°ç¬¬ä¸‰çº§èœå•
          if (grandChild.query) {
            console.log('跳转到:', fullPath, '带参数:', grandChild.query);
            router.push({ path: fullPath, query: grandChild.query });
          } else {
            console.log('跳转到:', fullPath);
            router.push({ path: fullPath });
          }
          return;
        }
      }
    }
    console.log('处理标准二级菜单');
    // æ£€æŸ¥æ˜¯å¦éœ€è¦ä½¿ç”¨parentPath
    if (firstVisibleChild.parentPath && firstVisibleChild.path.startsWith('/')) {
      console.log('使用parentPath属性:', firstVisibleChild.parentPath);
      // å¦‚果子菜单是绝对路径,但有parentPath,则应该使用parentPath作为基础
      let fullPath = firstVisibleChild.parentPath;
      if (!fullPath.startsWith('/')) {
        fullPath = '/' + fullPath;
      }
      // æž„建完整路径
      if (firstVisibleChild.path.startsWith('/')) {
        // æˆªå–子路径的最后部分
        const pathParts = firstVisibleChild.path.split('/');
        const lastPart = pathParts[pathParts.length - 1];
        fullPath = fullPath + '/' + lastPart;
      } else {
        fullPath = buildFullPath(fullPath, firstVisibleChild.path);
      }
      console.log('构建的最终路径:', fullPath);
      // å¯¼èˆªåˆ°ç›®æ ‡è·¯ç”±
      if (firstVisibleChild.query) {
        router.push({ path: fullPath, query: firstVisibleChild.query });
      } else {
        router.push({ path: fullPath });
      }
      return;
    }
    // æ ‡å‡†çš„二级菜单处理
    // æž„建正确的路径
    let fullPath;
    // å¤„理第一级路径(例如/system)- å¿…须是完整的路径
    if (currentNode.path.startsWith('/')) {
      fullPath = currentNode.path;
    } else {
      fullPath = '/' + currentNode.path;
    }
    console.log('一级路径:', fullPath);
    // å¤„理第二级路径(例如/system/user)- å¿…须基于第一级路径
    fullPath = buildFullPath(fullPath, firstVisibleChild.path);
    console.log('二级路径 (最终):', fullPath);
    // å¯¼èˆªåˆ°ç›®æ ‡è·¯ç”±
    if (firstVisibleChild.query) {
      console.log('跳转到:', fullPath, '带参数:', firstVisibleChild.query);
      router.push({ path: fullPath, query: firstVisibleChild.query });
    } else {
      console.log('跳转到:', fullPath);
      router.push({ path: fullPath });
    }
  }
}
function hasOneShowingChild(children = [], parent) {
  if (!children) {
    children = [];
@@ -65,8 +266,13 @@
  })
  // When there is only one child router, the child router is displayed by default
  if (showingChildren.length === 1) {
  if (showingChildren.length === 1 && !showingChildren[0].children) {
    return true
  }
  // If the single child also has children, don't treat it as a single showing child
  if (showingChildren.length === 1 && showingChildren[0].children && showingChildren[0].children.length > 0) {
    return false
  }
  // Show parent if there are no child router to display
@@ -86,12 +292,34 @@
    return props.basePath
  }
  if (routeQuery) {
    let query = JSON.parse(routeQuery);
    let query = routeQuery;
    // å¦‚æžœ routeQuery æ˜¯å­—符串,则尝试解析它
    if (typeof routeQuery === 'string') {
      try {
        query = JSON.parse(routeQuery);
      } catch (error) {
        console.error('Error parsing query string:', routeQuery, error);
      }
    }
    return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
  }
  return getNormalPath(props.basePath + '/' + routePath)
}
// æ­£ç¡®æž„建路径
function buildFullPath(base, segment) {
  // å¦‚æžœsegment是绝对路径,直接返回
  if (segment.startsWith('/')) {
    return segment;
  }
  // ç¡®ä¿base有正确的开头斜杠
  const normalizedBase = base.startsWith('/') ? base : '/' + base;
  // æ‹¼æŽ¥è·¯å¾„,避免双斜杠
  return normalizedBase.endsWith('/') ? normalizedBase + segment : normalizedBase + '/' + segment;
}
function hasTitle(title){
  if (title.length > 5) {
    return title;
zhitan-vue/src/layout/components/Sidebar/index.vue
@@ -2,44 +2,124 @@
  <div
    :class="{ 'has-logo': showLogo }"
    :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"
    class="sidebar-container-wrapper"
  >
    <logo v-if="showLogo" :collapse="isCollapse" />
    <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
    <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper" view-class="scrollbar-view">
      <!-- å§‹ç»ˆæ˜¾ç¤ºèœå•项,不再根据路径判断 -->
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        :background-color="sideTheme === 'theme-dark' ? '#232D70' : '#fff'"
        :background-color="'transparent'"
        :text-color="sideTheme === 'theme-dark' ? '#fff' : '#000'"
        :unique-opened="true"
        :active-text-color="theme"
        :collapse-transition="false"
        mode="vertical"
        class="custom-menu"
      >
        <!-- å½“前是首页看板子路由时,渲染专用路由 -->
        <template v-if="isIndexSubRoute">
          <sidebar-item
            v-for="(route, index) in indexPageRouters"
            :key="route.path + index"
            :item="route"
            :base-path="route.path"
          />
        </template>
        <template v-else>
        <sidebar-item
          v-for="(route, index) in sidebarRouters"
          :key="route.path + index"
          :item="route"
          :base-path="route.path"
        />
        </template>
      </el-menu>
    </el-scrollbar>
    <!-- åº•部用户区域 -->
    <div class="sidebar-footer" :class="{ 'collapsed': isCollapse, 'theme-light': sideTheme === 'theme-light' }">
      <div class="user-avatar-container">
        <img :src="userStore.avatar" class="user-avatar" />
      </div>
      <!-- å±•开状态下显示完整内容 -->
      <div class="user-info" v-if="!isCollapse">
        <div class="username">{{ userStore.name || 'admin' }}</div>
        <div class="action-buttons">
          <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile">
            <el-icon><User /></el-icon>
            <span>个人中心</span>
          </div>
          <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme">
            <el-icon><Brush /></el-icon>
            <span>切换主题</span>
          </div>
          <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout">
            <el-icon><SwitchButton /></el-icon>
            <span>退出登录</span>
          </div>
        </div>
      </div>
      <!-- æŠ˜å çŠ¶æ€ä¸‹åªæ˜¾ç¤ºå›¾æ ‡æŒ‰é’® -->
      <div class="collapsed-actions" v-if="isCollapse">
        <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile" title="个人中心">
          <el-icon><User /></el-icon>
        </div>
        <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme" title="切换主题">
          <el-icon><Brush /></el-icon>
        </div>
        <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout" title="退出登录">
          <el-icon><SwitchButton /></el-icon>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import Logo from "./Logo"
import SidebarItem from "./SidebarItem"
import variables from "@/assets/styles/variables.module.scss"
import useAppStore from "@/store/modules/app"
import useSettingsStore from "@/store/modules/settings"
import usePermissionStore from "@/store/modules/permission"
import useUserStore from "@/store/modules/user"
import { User, Brush, SwitchButton } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
const router = useRouter()
const route = useRoute()
const appStore = useAppStore()
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
const userStore = useUserStore()
const sidebarRouters = computed(() => permissionStore.sidebarRouters)
// åˆ¤æ–­å½“前是否为首页子路由(/index/index)
const isIndexSubRoute = computed(() => {
  return route.path === '/index/index'
})
// åˆ¤æ–­å½“前是否为主首页路由(/index或/)
const isMainIndexRoute = computed(() => {
  return route.path === '/index' || route.path === '/'
})
// é¦–页专用路由,首页看板相关菜单
const indexPageRouters = computed(() => {
  // æŸ¥æ‰¾name为Index的路由
  const indexRoute = sidebarRouters.value.find(route => route.name === 'Index')
  return indexRoute ? [indexRoute] : []
})
const showLogo = computed(() => settingsStore.sidebarLogo)
const sideTheme = computed(() => settingsStore.sideTheme)
const theme = computed(() => settingsStore.theme)
@@ -53,5 +133,465 @@
  }
  return path
})
function toUserProfile() {
  router.push('/user/profile')
}
function toggleTheme() {
  if (settingsStore.sideTheme == "theme-dark") {
    settingsStore.sideTheme = "theme-light"
    document.querySelector("body").className = "themeLight"
  } else {
    settingsStore.sideTheme = "theme-dark"
    document.querySelector("body").className = "themeDark"
  }
}
function handleLogout() {
  ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      userStore.logOut().then(() => {
        location.href = "/index"
      })
    })
    .catch(() => {})
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.sidebar-container-wrapper {
  position: relative;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
:deep(.scrollbar-wrapper) {
  height: calc(100% - 220px) !important;
  overflow-x: hidden !important;
}
:deep(.scrollbar-view) {
  height: 100%;
  padding-bottom: 20px;
}
:deep(.el-scrollbar__bar.is-vertical) {
  right: 0;
  width: 6px;
}
:deep(.el-scrollbar__thumb) {
  background-color: rgba(144, 147, 153, 0.3);
  &:hover {
    background-color: rgba(144, 147, 153, 0.5);
  }
}
.custom-menu {
  width: 100%;
  padding: 6px 0;
  height: auto !important; // æ”¹ä¸ºè‡ªé€‚应高度,避免固定高度导致内容溢出
  transition: all 0.3s ease;
  // Override Element Plus default menu styles
  .el-menu-item {
    height: 38px !important;
    line-height: 38px !important;
    border-radius: 4px;
    margin: 4px 10px;
    width: calc(100% - 20px);
    transition: all 0.2s ease;
    &.is-active {
      background-color: #3883FA !important;
      color: #fff !important;
      font-weight: bold;
      position: relative;
      box-shadow: 0 2px 8px rgba(56, 131, 250, 0.5);
      // å·¦ä¾§æŒ‡ç¤ºæ¡
    }
    &:hover {
      background-color: rgba(56, 131, 250, 0.1) !important;
    }
  }
  .el-sub-menu {
    .el-sub-menu__title {
      height: 38px !important;
      line-height: 38px !important;
      border-radius: 4px;
      margin: 4px 10px;
      width: calc(100% - 20px);
      transition: all 0.2s ease;
      &:hover {
        background-color: rgba(56, 131, 250, 0.1) !important;
      }
    }
    &.is-active {
      > .el-sub-menu__title {
        color: #3883FA !important;
        font-weight: bold;
      }
    }
    .el-menu-item {
      padding-left: 45px !important;
      min-width: auto !important;
      &.is-active {
        padding-left: 45px !important;
      }
    }
    // For nested submenus
    .el-menu {
      .el-menu-item,
      .el-sub-menu__title {
        height: 38px !important;
        line-height: 38px !important;
      }
      // Add styling for deeply nested submenus (level 3+)
      .el-sub-menu {
        .el-menu-item {
          padding-left: 65px !important;
          &.is-active {
            padding-left: 65px !important;
          }
        }
        // Level 4
        .el-menu {
          .el-menu-item {
            padding-left: 85px !important;
            &.is-active {
              padding-left: 85px !important;
            }
          }
        }
      }
    }
  }
}
// é¦–页空白菜单区域样式
.home-empty-menu {
  height: auto;
  min-height: 100px;
}
// åº•部用户区域样式
.sidebar-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  &.collapsed {
    padding: 10px;
    .user-avatar-container {
      margin-bottom: 10px;
    }
  }
  &.theme-light {
    background-color: rgba(255, 255, 255, 0.6);
    border-top: 1px solid rgba(0, 0, 0, 0.1);
    .user-avatar-container {
      border-color: rgba(0, 0, 0, 0.1);
    }
    .user-info {
      .username {
        color: #333;
      }
    }
  }
  .user-avatar-container {
    margin-bottom: 10px;
    border: 2px dashed rgba(255, 255, 255, 0.3);
    border-radius: 4px;
    width: 54px;
    height: 54px;
    display: flex;
    align-items: center;
    justify-content: center;
    .user-avatar {
      width: 38px;
      height: 38px;
      border-radius: 4px;
    }
  }
  .user-info {
    width: 100%;
    text-align: center;
    .username {
      color: #fff;
      font-size: 16px;
      font-weight: 500;
      margin-bottom: 16px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .action-buttons {
      .action-button {
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(56, 131, 250, 0.11);
        border-radius: 9px;
        border: 1px solid rgba(255, 255, 255, 0.3);
        color: #fff;
        padding: 10px;
        margin-bottom: 10px;
        border-radius: 4px;
        cursor: pointer;
        transition: background-color 0.3s;
        &:hover {
          background: rgba(56, 131, 250, 0.2);
        }
        .el-icon {
          margin-right: 8px;
          font-size: 16px;
        }
        span {
          font-size: 14px;
        }
        &.theme-light {
          background-color: rgba(56, 131, 250, 1);
          color: #fff;
          border: 1px solid rgba(56, 131, 250, 0.8);
          &:hover {
            background-color: rgba(56, 131, 250, 0.9);
          }
          .el-icon {
            color: #fff;
          }
        }
      }
    }
  }
  .collapsed-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    .action-icon {
      width: 40px;
      height: 40px;
      margin-bottom: 8px;
      background: rgba(56, 131, 250, 0.11);
      border: 1px solid rgba(255, 255, 255, 0.3);
      border-radius: 4px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      &:hover {
        background: rgba(56, 131, 250, 0.2);
      }
      .el-icon {
        font-size: 20px;
        color: #fff;
      }
      &.theme-light {
        background: rgba(56, 131, 250, 1);
        border: 1px solid rgba(56, 131, 250, 0.8);
        &:hover {
          background: rgba(56, 131, 250, 0.9);
        }
        .el-icon {
          color: #fff;
        }
      }
    }
  }
}
.theme-light {
  :deep(.custom-menu) {
    // Override Element Plus menu styles for light theme
    .el-menu-item {
      &.is-active {
        background-color: #3883FA !important;
        color: #fff !important;
      }
      &:hover {
        background-color: rgba(56, 131, 250, 0.1) !important;
      }
    }
    .el-sub-menu {
      .el-sub-menu__title {
        &:hover {
          background-color: rgba(56, 131, 250, 0.1) !important;
        }
      }
    }
  }
}
// æ·»åŠ æ·±è‰²æ¨¡å¼ä¸“ç”¨æ ·å¼
.theme-dark {
  :deep(.custom-menu) {
    // Override Element Plus menu styles for dark theme
    .el-menu-item {
      &.is-active {
        background-color: #4e77f8 !important;
        color: #ffffff !important;
        font-weight: bold;
        box-shadow: 0 2px 10px rgba(78, 119, 248, 0.6);
        position: relative;
        // å·¦ä¾§æŒ‡ç¤ºæ¡
      }
      &:hover {
        background-color: rgba(78, 119, 248, 0.2) !important;
      }
    }
    .el-sub-menu {
      &.is-active {
        > .el-sub-menu__title {
          color: #4e77f8 !important;
          font-weight: bold;
        }
      }
      .el-sub-menu__title {
        &:hover {
          background-color: rgba(78, 119, 248, 0.2) !important;
        }
      }
      // åµŒå¥—子菜单样式
      .el-menu {
        .el-menu-item {
          &.is-active {
            background-color: #4e77f8 !important;
            color: #ffffff !important;
          }
        }
        .el-sub-menu {
          &.is-active {
            > .el-sub-menu__title {
              color: #4e77f8 !important;
            }
          }
        }
      }
    }
  }
}
// Add global style to override Element Plus defaults
:global(.el-menu--vertical .el-menu-item),
:global(.el-menu--vertical .el-sub-menu__title) {
  height: 38px !important;
  line-height: 38px !important;
}
// Add styles for collapsed menu items
:deep(.custom-menu.el-menu--collapse) {
  width: 54px !important;
  .el-menu-item, .el-sub-menu__title {
    width: 36px !important;
    min-width: 36px !important;
    margin: 4px 9px !important; /* 9px是为了确保居中:(54px宽 - 36px菜单项) / 2 = 9px */
    padding: 0 !important;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 4px;
    &.is-active {
      background-color: #3883FA !important;
      color: #fff !important;
      box-shadow: 0 2px 6px rgba(56, 131, 250, 0.4);
      transform: scale(0.95);
      transition: all 0.2s ease;
    }
    .el-icon, .svg-icon {
      margin: 0 !important;
      font-size: 18px !important;
      svg {
        width: 1.2em;
        height: 1.2em;
      }
    }
    // ç¡®ä¿æŠ˜å æ—¶å­èœå•的标题也居中对齐
    .el-sub-menu__icon-arrow {
      display: none;
    }
  }
  // ç¡®ä¿æŠ˜å æ—¶å¼¹å‡ºçš„子菜单有正确样式
  .el-tooltip__trigger:focus:not(.focusing) {
    outline: none;
  }
}
// æ·±è‰²æ¨¡å¼ä¸‹æŠ˜å èœå•的样式
.theme-dark {
  :deep(.custom-menu.el-menu--collapse) {
    .el-menu-item, .el-sub-menu__title {
      &.is-active {
        background-color: #4e77f8 !important;
        color: #ffffff !important;
        box-shadow: 0 2px 8px rgba(78, 119, 248, 0.6);
      }
      &:hover {
        background-color: rgba(78, 119, 248, 0.2) !important;
      }
    }
  }
}
</style>
zhitan-vue/src/layout/components/TagsView/ScrollPane.vue
@@ -99,7 +99,7 @@
    bottom: 0px;
  }
  :deep(.el-scrollbar__wrap) {
    height: 39px;
    height: 34px !important;
  }
}
</style>
zhitan-vue/src/layout/components/TagsView/index.vue
@@ -1,5 +1,5 @@
<template>
  <div id="tags-view-container" class="tags-view-container">
  <div id="tags-view-container" class="tags-view-container" :class="{'theme-dark': sideTheme === 'theme-dark', 'theme-light': sideTheme === 'theme-light'}">
    <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll">
      <router-link
        v-for="tag in visitedViews"
@@ -52,6 +52,7 @@
const visitedViews = computed(() => useTagsViewStore().visitedViews)
const routes = computed(() => usePermissionStore().routes)
const theme = computed(() => useSettingsStore().theme)
const sideTheme = computed(() => useSettingsStore().sideTheme)
watch(route, () => {
  addTags()
@@ -232,104 +233,60 @@
</script>
<style lang="scss" scoped>
.themeDark {
  .tags-view-container {
    height: 56px;
    width: 100%;
    background: #1a235d;
    // border-bottom: 1px solid #d8dce5;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
    .tags-view-wrapper {
      .tags-view-item {
        display: inline-block;
        position: relative;
        cursor: pointer;
        height: 36px;
        line-height: 36px;
        border: 1px solid #5278f5;
        color: #fff;
        // background: #3271eb;
        padding: 0 14px;
        font-size: 14px;
        margin-left: 6px;
  height: 34px;
  width: calc(100% - 42px);
        margin-top: 10px;
        border-radius: 4px;
        font-family: OPPOSans, OPPOSans;
        &:first-of-type {
          margin-left: 16px;
        }
        &:last-of-type {
          margin-right: 15px;
        }
        &.active {
          background-color: #4e77f8 !important;
  margin-left: 14px;
  box-sizing: border-box;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
  &.theme-dark {
    background: #0A3465;
    .tags-view-item {
          color: #fff;
          border-color: #4e77f8 !important;
          &::before {
            content: "";
            background: #fff;
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            position: relative;
            margin-right: 5px;
          }
        }
      }
    }
    .contextmenu {
      margin: 0;
      background: #fff;
      z-index: 3000;
      position: absolute;
      list-style-type: none;
      padding: 5px 0;
      border-radius: 4px;
      font-size: 12px;
      font-weight: 400;
      color: #333;
      box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
      li {
        margin: 0;
        padding: 7px 16px;
        cursor: pointer;
        &:hover {
          background: #eee;
        }
      }
      border: 1px solid #0c4685;
      background: rgba(10, 52, 101, .48);
      border-radius: 5px;
      &.active {
        background-color: var(--el-color-primary) !important;
        color: #fff !important;
    }
  }
}
.themeLight {
  .tags-view-container {
    height: 56px;
    width: 100%;
  &.theme-light {
    background: #fff;
    // border-bottom: 1px solid #d8dce5;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
    .tags-view-item {
      color: #495060;
      background: #fff;
      border: 1px solid #d8dce5;
      &.active {
        background-color: var(--el-color-primary) !important;
        color: #fff !important;
      }
    }
  }
    .tags-view-wrapper {
      .tags-view-item {
        display: inline-block;
        position: relative;
        cursor: pointer;
        height: 36px;
        line-height: 36px;
        border: 1px solid #d8dce5;
        color: #495060;
        background: #fff;
        padding: 0 14px;
        font-size: 14px;
        margin-left: 6px;
        margin-top: 10px;
        border-radius: 4px;
        font-family: OPPOSans, OPPOSans;
      height: 26px;
      line-height: 26px;
      border-radius: 3px;
      padding: 0 10px;
      font-size: 12px;
      margin-left: 5px;
      margin-top: 4px;
        &:first-of-type {
          margin-left: 16px;
        margin-left: 5px;
        }
        &:last-of-type {
          margin-right: 15px;
        margin-right: 5px;
        }
        &.active {
          background-color: #42b983;
@@ -343,7 +300,7 @@
            height: 8px;
            border-radius: 50%;
            position: relative;
            margin-right: 5px;
          margin-right: 2px;
          }
        }
      }
@@ -366,7 +323,6 @@
        cursor: pointer;
        &:hover {
          background: #eee;
        }
      }
    }
  }
@@ -401,6 +357,6 @@
}
.scroll-container .el-scrollbar__wrap {
  height: 50px !important;
  height: 34px !important;
}
</style>
zhitan-vue/src/layout/index.vue
@@ -1,34 +1,99 @@
<template>
  <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
    <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
    <div class="navbar-container">
      <div class="navbar">
        <div class="left">
          <div class="sidebar-logo-container" :class="{ collapse: !sidebar.opened }">
            <div class="logo" v-if="systemInfo && systemInfo.leftLogo">
              <img v-if="sideTheme === 'theme-dark'" :src="systemInfo.leftLogo" class="sidebar-logo" />
              <img v-else :src="systemInfo.leftLogo" class="sidebar-logo" />
            </div>
            <div class="name" v-if="sidebar.opened" :style="{ color: sideTheme === 'theme-dark' ? '#fff' : '#333' }">
              {{ title }}
            </div>
          </div>
          <hamburger
            id="hamburger-container"
            :is-active="appStore.sidebar.opened"
            class="hamburger-container"
            @toggleClick="toggleSideBar"
          />
        </div>
        <top-nav />
        <div class="right">
          <!-- æŠ¥è­¦å’Œå¤§æ¨¡åž‹æŒ‰é’® -->
          <div class="right-menu">
            <!-- æŠ¥è­¦æŒ‰é’® -->
            <div class="right-menu-item alarm-btn" @click="goToAlarm">
              <el-badge :value="alarmCount" :max="99" class="alarm-badge">
                <svg-icon icon-class="bell" class="right-menu-icon" />
              </el-badge>
              <span class="right-menu-text">报警</span>
            </div>
            <!-- å¤§æ¨¡åž‹æŒ‰é’® -->
            <div class="right-menu-item ai-btn" @click="openAIModel">
              <svg-icon icon-class="ai" class="right-menu-icon" />
              <span class="right-menu-text">智能助手</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="content-container">
    <sidebar v-if="!sidebar.hide" class="sidebar-container" />
    <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
      <div :class="{ 'fixed-header': fixedHeader }">
        <navbar @setLayout="setLayout" v-if="!sidebar.hide"/>
        <tags-view v-if="needTagsView" v-show="!sidebar.hide"/>
      </div>
      <app-main />
      <settings ref="settingRef" />
    </div>
  </div>
  </div>
</template>
<script setup>
import { ref, computed, watchEffect, onMounted } from 'vue'
import { useWindowSize } from '@vueuse/core'
import { useRoute, useRouter } from 'vue-router'
import Sidebar from './components/Sidebar/index.vue'
import { AppMain, Navbar, Settings, TagsView } from './components'
import { AppMain, Settings, TagsView } from './components'
import TopNav from '@/components/TopNav'
import Hamburger from '@/components/Hamburger'
import defaultSettings from '@/settings'
import Cookies from "js-cookie"
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
const route = useRoute()
const router = useRouter()
const appStore = useAppStore()
const settingsStore = useSettingsStore()
const theme = computed(() => settingsStore.theme);
const sideTheme = computed(() => settingsStore.sideTheme);
const sidebar = computed(() => useAppStore().sidebar);
const device = computed(() => useAppStore().device);
const sidebar = computed(() => appStore.sidebar);
const device = computed(() => appStore.device);
const needTagsView = computed(() => settingsStore.tagsView);
const fixedHeader = computed(() => settingsStore.fixedHeader);
const systemInfo = JSON.parse(Cookies.get("SystemInfo") || '{"systemName":"智汕能源管理系统","leftLogo":""}')
const title = systemInfo.systemName || import.meta.env.VITE_APP_TITLE
// æŠ¥è­¦æ•°é‡ï¼Œå¯ä»¥ä»ŽæŽ¥å£èŽ·å–
const alarmCount = ref(5)
// è·³è½¬åˆ°æŠ¥è­¦é¡µé¢
function goToAlarm() {
  router.push('/alarmmanage/measuremen?modelCode=BJGL')
}
// æ‰“å¼€AI大模型对话框
function openAIModel() {
  // è·³è½¬åˆ°æŒ‡å®šçš„URL
  window.open('https://deepseek.tan-zhonghe.com/chat', '_blank')
}
const classObj = computed(() => ({
  hideSidebar: !sidebar.value.opened,
@@ -38,22 +103,51 @@
}))
const { width, height } = useWindowSize();
const WIDTH = 992; // refer to Bootstrap's responsive design
const WIDTH = 992;
watchEffect(() => {
  if (device.value === 'mobile' && sidebar.value.opened) {
    useAppStore().closeSideBar({ withoutAnimation: false })
    appStore.closeSideBar({ withoutAnimation: false })
  }
  if (width.value - 1 < WIDTH) {
    useAppStore().toggleDevice('mobile')
    useAppStore().closeSideBar({ withoutAnimation: true })
    appStore.toggleDevice('mobile')
    appStore.closeSideBar({ withoutAnimation: true })
  } else {
    useAppStore().toggleDevice('desktop')
    appStore.toggleDevice('desktop')
  }
})
// ç›‘听路由变化,处理首页的侧边栏显示
watchEffect(() => {
  // æ£€æŸ¥æ˜¯å¦æ˜¯é¦–页路由,但排除/index/index子路由
  if ((route.path === '/index' || route.path === '/') && route.path !== '/index/index') {
    // é¦–页路由,确保侧边栏不隐藏,但状态是折叠的
    appStore.toggleSideBarHide(false) // æ”¹ä¸ºä¸éšè—ä¾§è¾¹æ 
  } else if (route.meta && route.meta.showSidebar === false) {
    // å¦‚果路由明确指定隐藏侧边栏
    appStore.toggleSideBarHide(true)
  } else {
    // å…¶ä»–路由,确保侧边栏可见
    appStore.toggleSideBarHide(false)
  }
})
// ç»„件挂载时,确保首页侧边栏状态正确
onMounted(() => {
  // å¦‚果当前是首页子页面,只确保侧边栏不被隐藏,但保持折叠/展开状态不变
  if (route.path === '/index/index') {
    // åªè®¾ç½®ä¸éšè—ä¾§è¾¹æ ï¼Œä½†ä¸æ”¹å˜å…¶å±•å¼€/折叠状态
    appStore.toggleSideBarHide(false)
    // ä¸å†å¼ºåˆ¶è®¾ç½®opened为true,保持用户之前的设置
  }
})
function handleClickOutside() {
  useAppStore().closeSideBar({ withoutAnimation: false })
  appStore.closeSideBar({ withoutAnimation: false })
}
function toggleSideBar() {
  appStore.toggleSideBar()
}
const settingRef = ref(null);
@@ -69,8 +163,11 @@
.app-wrapper {
  @include clearfix;
  position: relative;
  height: 100%;
  width: 100%;
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  &.mobile.openSidebar {
    position: fixed;
@@ -88,13 +185,138 @@
  z-index: 999;
}
.fixed-header {
.navbar-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  z-index: 1000;
  width: 100%;
}
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: var(--current-color);
  height: 60px;
  width: 100%;
  padding: 0;
  .left {
    display: flex;
    align-items: center;
    padding-left: 16px;
    .sidebar-logo-container {
      display: flex;
      align-items: center;
      height: 60px;
      padding: 0 15px;
      min-width: 220px;
      .logo {
        width: 40px;
        height: 40px;
        margin-right: 10px;
        flex-shrink: 0;
        .sidebar-logo {
          width: 100%;
          height: 100%;
        }
      }
      .name {
        font-family: OPPOSans, OPPOSans;
        font-weight: bold;
        font-size: 20px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      &.collapse {
        min-width: 70px;
        .name {
          display: none;
        }
      }
    }
  }
  .right {
    display: flex;
    align-items: center;
    padding-right: 20px;
    .right-menu {
      display: flex;
      align-items: center;
      .right-menu-item {
        display: flex;
        align-items: center;
        margin-left: 20px;
        cursor: pointer;
        color: #fff;
        font-size: 14px;
        transition: all 0.3s;
        &:hover {
          opacity: 0.8;
        }
        .right-menu-icon {
          font-size: 18px;
          margin-right: 5px;
        }
        .right-menu-text {
          margin-left: 5px;
        }
      }
      .alarm-badge {
        :deep(.el-badge__content) {
          background-color: #f56c6c;
        }
      }
    }
  }
}
.content-container {
  display: flex;
  position: relative;
  margin-top: 60px;
  height: calc(100vh - 60px);
  width: 100%;
  overflow: hidden;
}
.sidebar-container {
  position: relative;
  height: 100%;
  z-index: 900;
  flex-shrink: 0;
  width: $base-sidebar-width;
}
.fixed-header {
  position: fixed;
  top: 60px;
  right: 0;
  z-index: 9;
  width: calc(100% - #{$base-sidebar-width});
  transition: width 0.28s;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: 0;
}
.hideSidebar .fixed-header {
@@ -108,4 +330,44 @@
.mobile .fixed-header {
  width: 100%;
}
.main-container {
  flex: 1;
  position: relative;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  transition: margin-left 0.28s;
  box-sizing: border-box;
}
.hideSidebar .main-container {
  margin-left: 0;
}
.sidebarHide .main-container {
  margin-left: 0;
}
.mobile .main-container {
  margin-left: 0;
}
.hideSidebar .sidebar-container {
  width: 54px;
}
.sidebarHide .sidebar-container {
  display: none;
}
.themeDark {
  .navbar {
    background: #002866 !important;
  }
  .sidebar-container {
    background-color: #002866 !important;
  }
}
</style>
zhitan-vue/src/permission.js
@@ -8,10 +8,90 @@
import useUserStore from '@/store/modules/user'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import useTagsViewStore from '@/store/modules/tagsView'
NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register', '/energy']
/**
 * æŸ¥æ‰¾æœ€æ·±å±‚的子菜单并构建完整路径
 */
function findDeepestPath(route) {
  if (!route) return { path: null, query: null };
  // é¦–先添加当前节点的路径
  let currentNode = route;
  let pathSegments = [];
  if (currentNode.path) {
    pathSegments.push(currentNode.path);
  }
  // é€å±‚添加子路径
  while (currentNode.children && currentNode.children.length > 0) {
    const firstChild = currentNode.children.find(child => !child.hidden);
    if (!firstChild) break;
    // è·³è¿‡ParentView类型的中间节点
    if (firstChild.component === 'ParentView' ||
        (typeof firstChild.component === 'object' &&
         firstChild.component.name === 'ParentView')) {
      currentNode = firstChild;
      // å¦‚果路径不是以/开头,则添加到路径片段中
      if (!firstChild.path.startsWith('/')) {
        pathSegments.push(firstChild.path);
      } else {
        // å¦‚果是绝对路径,则替换之前所有路径
        pathSegments = [firstChild.path];
      }
      continue;
    }
    // æ™®é€šèŠ‚ç‚¹å¤„ç†
    currentNode = firstChild;
    // å¦‚果路径不是以/开头,则添加到路径片段中
    if (!firstChild.path.startsWith('/')) {
      pathSegments.push(firstChild.path);
    } else {
      // å¦‚果是绝对路径,则替换之前所有路径
      pathSegments = [firstChild.path];
    }
    // å¦‚果到达叶子节点,则结束查找
    if (!firstChild.children || firstChild.children.length === 0) {
      break;
    }
  }
  // æž„建最终路径
  let targetPath = '';
  if (pathSegments.length > 0) {
    // å¦‚果第一段不是以/开头,添加/
    if (!pathSegments[0].startsWith('/')) {
      pathSegments[0] = '/' + pathSegments[0];
    }
    // ç»„合路径
    targetPath = pathSegments.reduce((fullPath, segment, index) => {
      if (segment.startsWith('/')) {
        return segment;
      } else if (index === 0) {
        return segment;
      } else {
        // ç¡®ä¿è·¯å¾„之间不会出现重复的斜杠
        const base = fullPath.endsWith('/') ? fullPath.slice(0, -1) : fullPath;
        const part = segment.startsWith('/') ? segment : '/' + segment;
        return `${base}${part}`;
      }
    });
  }
  return {
    path: targetPath,
    query: currentNode.query
  };
}
router.beforeEach((to, from, next) => {
  NProgress.start()
@@ -36,6 +116,40 @@
                router.addRoute(route) // åŠ¨æ€æ·»åŠ å¯è®¿é—®è·¯ç”±è¡¨
              }
            })
            // å¦‚果是首页,自动重定向到第一个菜单
            if (to.path === '/' || to.path === '/index') {
              const permissionStore = usePermissionStore()
              const topMenus = permissionStore.topbarRouters.filter(menu => !menu.hidden)
              if (topMenus.length > 0) {
                // è·³è½¬åˆ°ç¬¬ä¸€ä¸ªèœå•
                const firstMenu = topMenus[0]
                // æŸ¥æ‰¾æœ€æ·±å±‚的子菜单并构建路径
                const { path, query } = findDeepestPath(firstMenu);
                if (path) {
                  // æœ‰æœ€æ·±å±‚子菜单,跳转到该菜单
                  if (query) {
                    next({ path, query, replace: true });
                  } else {
                    next({ path, replace: true });
                  }
                  return;
                } else if (firstMenu.children && firstMenu.children.length > 0) {
                  // ä½¿ç”¨åŽŸæœ‰é€»è¾‘
                  const firstChild = firstMenu.children[0]
                  const childPath = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
                  next({ path: childPath, replace: true })
                  return
                } else {
                  // æ²¡æœ‰å­èœå•,直接跳转
                  next({ path: firstMenu.path, replace: true })
                  return
                }
              }
            }
            next({ ...to, replace: true }) // hack方法 ç¡®ä¿addRoutes已完成
          })
        }).catch(err => {
@@ -45,6 +159,58 @@
          })
        })
      } else {
        // å¦‚果是首页,自动重定向到第一个菜单
        if (to.path === '/' || to.path === '/index') {
          const permissionStore = usePermissionStore()
          const topMenus = permissionStore.topbarRouters.filter(menu => !menu.hidden)
          if (topMenus.length > 0) {
            // è·³è½¬åˆ°ç¬¬ä¸€ä¸ªèœå•
            const firstMenu = topMenus[0]
            // æŸ¥æ‰¾æœ€æ·±å±‚的子菜单并构建路径
            const { path, query } = findDeepestPath(firstMenu);
            if (path) {
              // æœ‰æœ€æ·±å±‚子菜单,跳转到该菜单
              if (query) {
                next({ path, query, replace: true });
              } else {
                next({ path, replace: true });
              }
              return;
            } else if (firstMenu.children && firstMenu.children.length > 0) {
              // ä½¿ç”¨åŽŸæœ‰é€»è¾‘
              const firstChild = firstMenu.children[0]
              const childPath = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}`
              next({ path: childPath, replace: true })
              return
            } else {
              // æ²¡æœ‰å­èœå•,直接跳转
              next({ path: firstMenu.path, replace: true })
              return
            }
          }
        }
        // è‡ªåŠ¨å¤„ç†å¸¦æœ‰é‡å®šå‘çš„è·¯ç”±
        if (to.matched.length > 0 && to.matched[0].path === to.path) {
          const currentRouteConfig = router.getRoutes().find(r => r.path === to.path);
          if (currentRouteConfig && currentRouteConfig.children && currentRouteConfig.children.length > 0) {
            // æœ‰å­è·¯ç”±ï¼Œè‡ªåŠ¨å¯¼èˆªåˆ°æœ€æ·±å±‚å­èœå•
            const { path, query } = findDeepestPath(currentRouteConfig);
            if (path && path !== to.path) {
              if (query) {
                next({ path, query, replace: true });
              } else {
                next({ path, replace: true });
              }
              return;
            }
          }
        }
        next()
      }
    }
@@ -62,4 +228,12 @@
router.afterEach(() => {
  NProgress.done()
  // ç§»é™¤æ‰€æœ‰å¯èƒ½çš„首页标签
  const tagsViewStore = useTagsViewStore();
  if (tagsViewStore && tagsViewStore.visitedViews) {
    tagsViewStore.visitedViews = tagsViewStore.visitedViews.filter(
      tag => tag.path !== '/index' && tag.path !== '/' && tag.name !== 'Index'
    );
  }
})
zhitan-vue/src/router/index.js
@@ -1,6 +1,7 @@
import { createWebHistory, createRouter } from 'vue-router'
/* Layout */
import Layout from '@/layout'
import useAppStore from '@/store/modules/app'
/**
 * Note: è·¯ç”±é…ç½®é¡¹
@@ -66,7 +67,7 @@
        path: '/index',
        component: () => import('@/views/index'),
        name: 'Index',
        meta: { title: '首页', icon: 'dashboard', affix: true }
        meta: { title: '首页', icon: 'dashboard', affix: true, showSidebar: true, breadcrumb: false }
      }
    ]
  },
zhitan-vue/src/store/modules/app.js
@@ -7,7 +7,7 @@
      sidebar: {
        opened: sessionStorage.getItem('sidebarStatus') ? !!+sessionStorage.getItem('sidebarStatus') : true,
        withoutAnimation: false,
        hide: false
        hide: sessionStorage.getItem('sidebarHide') ? JSON.parse(sessionStorage.getItem('sidebarHide')) : false
      },
      device: 'desktop',
      size: sessionStorage.getItem('size') || 'default'
@@ -39,6 +39,20 @@
      },
      toggleSideBarHide(status) {
        this.sidebar.hide = status
        sessionStorage.setItem('sidebarHide', status)
      },
      openMenu() {
        this.sidebar.hide = false
        this.sidebar.opened = true
        sessionStorage.setItem('sidebarHide', 'false')
        sessionStorage.setItem('sidebarStatus', 1)
      },
      showCollapsedSidebar() {
        this.sidebar.hide = false
        this.sidebar.opened = false
        this.sidebar.withoutAnimation = false
        sessionStorage.setItem('sidebarHide', 'false')
        sessionStorage.setItem('sidebarStatus', 0)
      }
    }
  })
zhitan-vue/src/store/modules/permission.js
@@ -56,8 +56,27 @@
  })
// éåŽ†åŽå°ä¼ æ¥çš„è·¯ç”±å­—ç¬¦ä¸²ï¼Œè½¬æ¢ä¸ºç»„ä»¶å¯¹è±¡
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false, parentRoute = null) {
  return asyncRouterMap.filter(route => {
    // ä¸å†è¿‡æ»¤æŽ‰é¦–页看板相关路由
    /*
    // è¿‡æ»¤æŽ‰é¦–页看板相关路由
    if (route.name === 'Index' && route.meta && route.meta.title === '首页看板') {
      return false;
    }
    // å¦‚果是首页看板的子菜单,也过滤掉
    if (route.path === '/index' || route.path === 'index' ||
        (route.meta && route.meta.title === '首页看板')) {
      return false;
    }
    */
    // è®¾ç½®çˆ¶è·¯ç”±å¼•用
    if (parentRoute) {
      route.parent = parentRoute;
    }
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
@@ -73,8 +92,17 @@
        route.component = loadView(route.component)
      }
    }
    // å¤„理 query å‚数,将字符串转换为对象
    if (route.query && typeof route.query === 'string') {
      try {
        route.query = JSON.parse(route.query);
      } catch (error) {
        console.error('Error parsing query string:', route.query, error);
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
      // å°†å½“前路由作为父路由传递给子路由
      route.children = filterAsyncRouter(route.children, route, type, route)
    } else {
      delete route['children']
      delete route['redirect']
@@ -89,7 +117,21 @@
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path
          // è®¾ç½®çˆ¶è·¯ç”±å¼•用
          c.parent = el;
          // ç¡®ä¿è·¯å¾„格式正确拼接
          if (el.path) {
            if (c.path.startsWith('/')) {
              // ç»å¯¹è·¯å¾„保持不变
              // ä½†ä¹Ÿè®¾ç½®åŽŸå§‹çˆ¶è·¯å¾„ç”¨äºŽèœå•å¯¼èˆª
              c.parentPath = el.path;
            } else {
              // ç›¸å¯¹è·¯å¾„需要拼接
              c.path = el.path.endsWith('/') ? el.path + c.path : el.path + '/' + c.path;
            }
          }
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c))
            return
@@ -100,7 +142,21 @@
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path
      // è®¾ç½®çˆ¶è·¯ç”±å¼•用
      el.parent = lastRouter;
      // ç¡®ä¿è·¯å¾„格式正确拼接
      if (lastRouter.path) {
        if (el.path.startsWith('/')) {
          // ç»å¯¹è·¯å¾„保持不变
          // ä½†ä¹Ÿè®¾ç½®åŽŸå§‹çˆ¶è·¯å¾„ç”¨äºŽèœå•å¯¼èˆª
          el.parentPath = lastRouter.path;
        } else {
          // ç›¸å¯¹è·¯å¾„需要拼接
          el.path = lastRouter.path.endsWith('/') ? lastRouter.path + el.path : lastRouter.path + '/' + el.path;
        }
      }
      if (el.children && el.children.length) {
        children = children.concat(filterChildren(el.children, el))
        return
zhitan-vue/src/store/modules/settings.js
@@ -23,7 +23,7 @@
      // ä¿®æ”¹å¸ƒå±€è®¾ç½®
      changeSetting(data) {
        const { key, value } = data
        if (this.hasOwnProperty(key)) {
        if (key in this.$state) {
          this[key] = value
        }
      },
zhitan-vue/src/store/modules/tagsView.js
@@ -20,6 +20,11 @@
        )
      },
      addVisitedView(view) {
        // è¿‡æ»¤é¦–页标签
        if (view.path === '/index' || view.path === '/' || view.name === 'Index') {
          return;
        }
        if (this.visitedViews.some(v => v.path === view.path)) return
        this.visitedViews.push(
          Object.assign({}, view, {
@@ -110,7 +115,8 @@
      },
      delAllVisitedViews(view) {
        return new Promise(resolve => {
          const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
          // è¿‡æ»¤æŽ‰é¦–页标签,只保留其他固定标签
          const affixTags = this.visitedViews.filter(tag => tag.meta.affix && tag.path !== '/index' && tag.path !== '/' && tag.name !== 'Index')
          this.visitedViews = affixTags
          this.iframeViews = []
          resolve([...this.visitedViews])
zhitan-vue/src/utils/ruoyi.js
@@ -1,5 +1,3 @@
/**
 * é€šç”¨js方法封装处理
 * Copyright (c) 2019 ruoyi
@@ -10,17 +8,20 @@
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}"
  let date
  if (typeof time === 'object') {
  if (typeof time === "object") {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
    if (typeof time === "string" && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
    } else if (typeof time === "string") {
      time = time
        .replace(new RegExp(/-/gm), "/")
        .replace("T", " ")
        .replace(new RegExp(/\.[\d]{3}/gm), "")
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
    if (typeof time === "number" && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
@@ -32,14 +33,16 @@
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
    a: date.getDay(),
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
    if (key === "a") {
      return ["日", "一", "二", "三", "四", "五", "六"][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
      value = "0" + value
    }
    return value || 0
  })
@@ -49,89 +52,92 @@
// è¡¨å•重置
export function resetForm(refName) {
  if (this.$refs[refName]) {
    this.$refs[refName].resetFields();
    this.$refs[refName].resetFields()
  }
}
// æ·»åŠ æ—¥æœŸèŒƒå›´
export function addDateRange(params, dateRange, propName) {
  let search = params;
  search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
  dateRange = Array.isArray(dateRange) ? dateRange : [];
  if (typeof (propName) === 'undefined') {
    search.params['beginTime'] = dateRange[0];
    search.params['endTime'] = dateRange[1];
  let search = params
  search.params =
    typeof search.params === "object" && search.params !== null && !Array.isArray(search.params) ? search.params : {}
  dateRange = Array.isArray(dateRange) ? dateRange : []
  if (typeof propName === "undefined") {
    search.params["beginTime"] = dateRange[0]
    search.params["endTime"] = dateRange[1]
  } else {
    search.params['begin' + propName] = dateRange[0];
    search.params['end' + propName] = dateRange[1];
    search.params["begin" + propName] = dateRange[0]
    search.params["end" + propName] = dateRange[1]
  }
  return search;
  return search
}
// å›žæ˜¾æ•°æ®å­—å…¸
export function selectDictLabel(datas, value) {
  if (value === undefined) {
    return "";
    return ""
  }
  var actions = [];
  var actions = []
  Object.keys(datas).some((key) => {
    if (datas[key].value == ('' + value)) {
      actions.push(datas[key].label);
      return true;
    if (datas[key].value == "" + value) {
      actions.push(datas[key].label)
      return true
    }
  })
  if (actions.length === 0) {
    actions.push(value);
    actions.push(value)
  }
  return actions.join('');
  return actions.join("")
}
// å›žæ˜¾æ•°æ®å­—典(字符串数组)
export function selectDictLabels(datas, value, separator) {
  if (value === undefined || value.length ===0) {
    return "";
    return ""
  }
  if (Array.isArray(value)) {
    value = value.join(",");
    value = value.join(",")
  }
  var actions = [];
  var currentSeparator = undefined === separator ? "," : separator;
  var temp = value.split(currentSeparator);
  var actions = []
  var currentSeparator = undefined === separator ? "," : separator
  var temp = value.split(currentSeparator)
  Object.keys(value.split(currentSeparator)).some((val) => {
    var match = false;
    var match = false
    Object.keys(datas).some((key) => {
      if (datas[key].value == ('' + temp[val])) {
        actions.push(datas[key].label + currentSeparator);
        match = true;
      if (datas[key].value == "" + temp[val]) {
        actions.push(datas[key].label + currentSeparator)
        match = true
      }
    })
    if (!match) {
      actions.push(temp[val] + currentSeparator);
      actions.push(temp[val] + currentSeparator)
    }
  })
  return actions.join('').substring(0, actions.join('').length - 1);
  return actions.join("").substring(0, actions.join("").length - 1)
}
// å­—符串格式化(%s )
export function sprintf(str) {
  var args = arguments, flag = true, i = 1;
  var args = arguments,
    flag = true,
    i = 1
  str = str.replace(/%s/g, function () {
    var arg = args[i++];
    if (typeof arg === 'undefined') {
      flag = false;
      return '';
    var arg = args[i++]
    if (typeof arg === "undefined") {
      flag = false
      return ""
    }
    return arg;
  });
  return flag ? str : '';
    return arg
  })
  return flag ? str : ""
}
// è½¬æ¢å­—符串,undefined,null等转化为""
export function parseStrEmpty(str) {
  if (!str || str == "undefined" || str == "null") {
    return "";
    return ""
  }
  return str;
  return str
}
// æ•°æ®åˆå¹¶
@@ -139,16 +145,16 @@
  for (var p in target) {
    try {
      if (target[p].constructor == Object) {
        source[p] = mergeRecursive(source[p], target[p]);
        source[p] = mergeRecursive(source[p], target[p])
      } else {
        source[p] = target[p];
        source[p] = target[p]
      }
    } catch (e) {
      source[p] = target[p];
      source[p] = target[p]
    }
  }
  return source;
};
  return source
}
/**
 * æž„造树型结构数据
@@ -159,46 +165,46 @@
 */
export function handleTree(data, id, parentId, children) {
  let config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children'
  };
    id: id || "id",
    parentId: parentId || "parentId",
    childrenList: children || "children",
  }
  var childrenListMap = {};
  var nodeIds = {};
  var tree = [];
  var childrenListMap = {}
  var nodeIds = {}
  var tree = []
  for (let d of data) {
    let parentId = d[config.parentId];
    let parentId = d[config.parentId]
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
      childrenListMap[parentId] = []
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
    nodeIds[d[config.id]] = d
    childrenListMap[parentId].push(d)
  }
  for (let d of data) {
    let parentId = d[config.parentId];
    let parentId = d[config.parentId]
    if (nodeIds[parentId] == null) {
      tree.push(d);
      tree.push(d)
    }
  }
  for (let t of tree) {
    adaptToChildrenList(t);
    adaptToChildrenList(t)
  }
  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
      o[config.childrenList] = childrenListMap[o[config.id]]
    }
    if (o[config.childrenList]) {
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c);
        adaptToChildrenList(c)
      }
    }
  }
  return tree;
  return tree
}
/**
@@ -206,41 +212,58 @@
* @param {*} params  å‚æ•°
*/
export function tansParams(params) {
  let result = ''
  let result = ""
  for (const propName of Object.keys(params)) {
    const value = params[propName];
    var part = encodeURIComponent(propName) + "=";
    if (value !== null && value !== "" && typeof (value) !== "undefined") {
      if (typeof value === 'object') {
    const value = params[propName]
    var part = encodeURIComponent(propName) + "="
    if (value !== null && value !== "" && typeof value !== "undefined") {
      if (typeof value === "object") {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
            let params = propName + '[' + key + ']';
            var subPart = encodeURIComponent(params) + "=";
            result += subPart + encodeURIComponent(value[key]) + "&";
          if (value[key] !== null && value[key] !== "" && typeof value[key] !== "undefined") {
            let params = propName + "[" + key + "]"
            var subPart = encodeURIComponent(params) + "="
            result += subPart + encodeURIComponent(value[key]) + "&"
          }
        }
      } else {
        result += part + encodeURIComponent(value) + "&";
        result += part + encodeURIComponent(value) + "&"
      }
    }
  }
  return result
}
// è¿”回项目路径
export function getNormalPath(p) {
  if (p.length === 0 || !p || p == 'undefined') {
  if (p.length === 0 || !p || p == "undefined") {
    return p
  };
  let res = p.replace('//', '/')
  if (res[res.length - 1] === '/') {
  }
  let res = p.replace("//", "/")
  if (res[res.length - 1] === "/") {
    return res.slice(0, res.length - 1)
  }
  return res;
  return res
}
// éªŒè¯æ˜¯å¦ä¸ºblob格式
export function blobValidate(data) {
  return data.type !== 'application/json'
  return data.type !== "application/json"
}
// é€šç”¨ä¸‹è½½æ–¹æ³•
const baseURL = import.meta.env.VITE_APP_BASE_API
export function download(fileName) {
  window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true
}
// é€šç”¨ä¸‹è½½æ–¹æ³• showfileName:下载后的文件名称带扩展名;filePath:要下载文件的绝对路径,带着文件名和扩展名;deleteflage下载完成后是否删除文件
export function fileDownload(showfileName, filePath, deleteflage) {
  window.location.href =
    baseURL +
    "/common/downloadAssign?showFileName=" +
    encodeURI(showfileName) +
    "&filePath=" +
    encodeURI(filePath) +
    "&delete=" +
    deleteflage
}
zhitan-vue/src/views/alarmmanage/alarmrecord/alarmRecord.vue
@@ -6,7 +6,7 @@
      </div>
      <div class="page-container-right">
        <div class="form-card">
          <el-form :model="form" ref="queryRef" :inline="true" label-width="85px">
          <el-form :model="form" ref="queryRef" :inline="true" label-width="68px">
            <el-form-item prop="eierarchyFlag">
              <el-radio-group v-model="form.eierarchyFlag">
                <el-radio label="B" name="eierarchyFlag">本级</el-radio>
@@ -14,14 +14,25 @@
              </el-radio-group>
            </el-form-item>
            <el-form-item label="时间选择">
              <el-date-picker v-model="form.dataTime" type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss" placeholder="时间" style="width: 370px" unlink-panels
                time-format="HH:mm:ss" />
              <el-date-picker
                v-model="form.dataTime"
                type="datetimerange"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                placeholder="时间"
                style="width: 340px"
                unlink-panels
                time-format="HH:mm:ss"
              />
            </el-form-item>
            <el-form-item label="报警类别" prop="indexType">
              <el-select v-model="form.indexType" placeholder="请选择报警类别" style="width: 200px">
                <el-option v-for="dict in alarm_record_category" :key="dict.value" :label="dict.label"
                  :value="dict.value" />
                <el-option
                  v-for="dict in alarm_record_category"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
            <!-- <el-form-item label="能源类型" prop="energyType">
@@ -39,18 +50,26 @@
            </el-form-item>
          </el-form>
        </div>
        <BaseCard :title="currentNode ? currentNode.label + '--节点配置' : '暂无节点配置'
          ">
        <BaseCard :title="currentNode ? currentNode.label + '--节点配置' : '暂无节点配置'">
          <div class="table-box">
            <el-table :data="tableData" v-loading="loading" height="calc(100vh - 450px)">
              <el-table-column type="index" label="序号" width="70" />
              <el-table-column label="用能单元" prop="modelName" align="center" show-overflow-tooltip />
              <el-table-column label="指标名称" prop="indexName" align="center" show-overflow-tooltip />
              <el-table-column label="报警类别" prop="indexType" align="center" show-overflow-tooltip :formatter="(row, column) =>
                proxy.selectDictLabel(alarm_record_category, row.indexType)
                " />
              <el-table-column label="能源类型" prop="energyId" align="center" show-overflow-tooltip :formatter="(row, column) => formatterLabel(energyTypeList, row.energyId)
                " />
              <el-table-column
                label="报警类别"
                prop="indexType"
                align="center"
                show-overflow-tooltip
                :formatter="(row, column) => proxy.selectDictLabel(alarm_record_category, row.indexType)"
              />
              <el-table-column
                label="能源类型"
                prop="energyId"
                align="center"
                show-overflow-tooltip
                :formatter="(row, column) => formatterLabel(energyTypeList, row.energyId)"
              />
              <el-table-column label="预设值" prop="energyType" align="center" show-overflow-tooltip />
              <el-table-column label="报警值" prop="alarmValue" align="center" show-overflow-tooltip />
              <el-table-column label="报警时间" prop="alarmBeginTime" align="center" show-overflow-tooltip />
@@ -58,17 +77,22 @@
          </div>
        </BaseCard>
        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize" @pagination="getList(currentNode)" />
        <pagination
          v-show="total > 0"
          :total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="getList(currentNode)"
        />
      </div>
    </div>
  </div>
</template>
<script setup name="alarmRecord">
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType";
const { proxy } = getCurrentInstance();
let { alarm_record_category } = proxy.useDict("alarm_record_category");
import { historicalAlarm } from "@/api/alarmManage/alarmManage";
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
const { proxy } = getCurrentInstance()
let { alarm_record_category } = proxy.useDict("alarm_record_category")
import { historicalAlarm } from "@/api/alarmManage/alarmManage"
let form = ref({
  eierarchyFlag: "B",
  dataTime: [
@@ -79,74 +103,77 @@
  indexType: "",
  // energyType: '',
  indexName: "",
});
const energyTypeList = ref();
})
const energyTypeList = ref()
function getEnergyTypeList() {
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data;
    form.value.indexType = alarm_record_category.value[0].value;
    energyTypeList.value = res.data
    form.value.indexType = alarm_record_category.value[0].value
    // form.value.energyType = energyTypeList.value[0].enersno
    getList();
  });
    getList()
  })
}
// getEnergyTypeList()
let currentNode = ref();
let currentNode = ref()
function handleNodeClick(data) {
  currentNode.value = data;
  getEnergyTypeList();
  currentNode.value = data
  getEnergyTypeList()
}
let tableData = ref([]);
let total = ref(0);
let loading = ref(false);
let tableData = ref([])
let total = ref(0)
let loading = ref(false)
let queryParams = ref({
  pageNum: 1,
  pageSize: 10,
});
})
function formatterLabel(list, value) {
  let dict = list.find((item) => item.enersno == value);
  return dict ? dict.enername : "";
  let dict = list.find((item) => item.enersno == value)
  return dict ? dict.enername : ""
}
function getList() {
  form.value.nodeId = currentNode.value.id;
  loading.value = true;
  form.value.nodeId = currentNode.value.id
  loading.value = true
  historicalAlarm({
    ...form.value,
    ...queryParams.value,
    beginTime: form.value.dataTime[0],
    endTime: form.value.dataTime[1],
  }).then((response) => {
    console.log(11, response);
    console.log(11, response)
    if (response.code === 200) {
      tableData.value = response.rows;
      total.value = response.total;
      loading.value = false;
      tableData.value = response.rows
      total.value = response.total
      loading.value = false
    } else {
      proxy.$modal.msgError(response.msg);
      proxy.$modal.msgError(response.msg)
    }
  });
  })
}
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
  queryParams.value.pageNum = 1
  getList()
}
function resetQuery() {
  form.value = {
    eierarchyFlag: 'B',
    dataTime: [proxy.dayjs(new Date()).format("YYYY-MM-DD 00:00:00"), proxy.dayjs(new Date()).format("YYYY-MM-DD 23:59:59")],
    nodeId: '',
    eierarchyFlag: "B",
    dataTime: [
      proxy.dayjs(new Date()).format("YYYY-MM-DD 00:00:00"),
      proxy.dayjs(new Date()).format("YYYY-MM-DD 23:59:59"),
    ],
    nodeId: "",
    indexType: alarm_record_category.value[0].value,
    // energyType: '',
    indexName: '',
    indexName: "",
  }
  queryParams.value = {
    pageNum: 1,
    pageSize: 10,
  };
  getList();
  }
  getList()
}
</script>
zhitan-vue/src/views/alarmmanage/energyconsumption/energyConsumption.vue
@@ -8,16 +8,28 @@
        <div class="form-card">
          <el-form :model="form" ref="queryRef" :inline="true" label-width="85px">
            <el-form-item label="期间" prop="timeType">
              <el-select v-model="queryParams.timeType" placeholder="期间" clearable style="width: 100%"
                @change="handleTimeType">
              <el-select
                v-model="queryParams.timeType"
                placeholder="期间"
                clearable
                style="width: 100%"
                @change="handleTimeType"
              >
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
              <el-date-picker v-model="queryParams.dataTime" :clearable="false"
              <el-date-picker
                v-model="queryParams.dataTime"
                :clearable="false"
                :type="queryParams.timeType == 'YEAR' ? 'year' : queryParams.timeType == 'MONTH' ? 'month' : 'date'"
                :format="queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'"
                value-format="YYYY-MM-DD" placeholder="时间" style="width: 100%" />
                :format="
                  queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'
                "
                value-format="YYYY-MM-DD"
                placeholder="时间"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -55,70 +67,69 @@
</template>
<script setup>
import * as echarts from 'echarts';
import { onMounted, reactive, ref } from 'vue';
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType";
const { proxy } = getCurrentInstance();
const { period } = proxy.useDict("period");
let { alarm_record_category } = proxy.useDict("alarm_record_category");
import * as echarts from "echarts"
import { onMounted, reactive, ref } from "vue"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
const { proxy } = getCurrentInstance()
const { period } = proxy.useDict("period")
let { alarm_record_category } = proxy.useDict("alarm_record_category")
let energyTypeList = ref([])
function getEnergyTypeList() {
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data;
  });
    energyTypeList.value = res.data
  })
}
getEnergyTypeList()
function formatterLabel(list, value) {
  console.log(list, value);
  console.log(list, value)
  let dict = list.find(item => item.enersno == value)
  return dict ? dict.enername : ''
  let dict = list.find((item) => item.enersno == value)
  return dict ? dict.enername : ""
}
let queryParams = ref({
  timeType: null,
  dataTime: null,
  nodeId: null
  nodeId: null,
})
import { getByNodeId, getCountInfo } from "@/api/alarmManage/alarmManage";
import { el } from 'element-plus/es/locales.mjs';
let form = ref({});
import { getByNodeId, getCountInfo } from "@/api/alarmManage/alarmManage"
import { el } from "element-plus/es/locales.mjs"
let form = ref({})
let currentNode = ref()
function handleTimeType(e) {
  queryParams.value.timeType = e;
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD");
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
}
function handleNodeClick(e) {
  currentNode.value = e
  queryParams.value.nodeId = e.id
  handleTimeType('YEAR')
  handleTimeType("YEAR")
  getByNodeIdFun()
}
function getByNodeIdFun() {
  getByNodeId(queryParams.value).then(res => {
  getByNodeId(queryParams.value).then((res) => {
    let alarmList = []
    let energyList = []
    let alarmNumberList = {
      data: [],
      xAxisData: []
      xAxisData: [],
    }
    console.log(111, res);
    console.log(111, res)
    if (res.code == 200) {
      let { data } = res
      alarmList = data.alarmProportion.map(item => {
      alarmList = data.alarmProportion.map((item) => {
        return {
          name: proxy.selectDictLabel(alarm_record_category.value, item.energyName),
          value: item.percentage
          value: item.percentage,
        }
      })
      energyList = data.energyProportion.map(item => {
      energyList = data.energyProportion.map((item) => {
        return {
          name: formatterLabel(energyTypeList.value, item.energyName),
          value: item.percentage
          value: item.percentage,
        }
      })
      for (const item of data.chartDataList) {
@@ -126,9 +137,9 @@
        alarmNumberList.data.push(item.yvalue)
      }
      pieChart('Chart1', alarmList, '报警类型占比')
      pieChart('Chart2', energyList, '能源类型占比')
      getChart('Chart3', alarmNumberList)
      pieChart("Chart1", alarmList, "报警类型占比")
      pieChart("Chart2", energyList, "能源类型占比")
      getChart("Chart3", alarmNumberList)
    }
  })
}
@@ -138,144 +149,151 @@
  getByNodeIdFun()
}
function resetQuery() {
  handleTimeType('YEAR')
  handleTimeType("YEAR")
  getByNodeIdFun()
}
function pieChart(Id, data, name) {
  let total = 0;
  let total = 0
  data.forEach(function (val, idx, arr) {
    total += val.value;
    total += val.value
  })
  const myChart = echarts.init(document.getElementById(Id));
  const myChart = echarts.init(document.getElementById(Id))
  myChart.setOption({
    color: ['#4D94FF', '#00C27C', '#F0142F', '#F2D261', '#0E7CE2', '#FF8352', '#E271DE', '#F8456B', '#00FFFF', '#4AEAB0'],
    color: [
      "#4D94FF",
      "#00C27C",
      "#F0142F",
      "#F2D261",
      "#0E7CE2",
      "#FF8352",
      "#E271DE",
      "#F8456B",
      "#00FFFF",
      "#4AEAB0",
    ],
    grid: {
      top: '20%',
      left: '1%',
      right: '1%',
      bottom: '0%',
      containLabel: true
      top: "20%",
      left: "1%",
      right: "1%",
      bottom: "0%",
      containLabel: true,
    },
    tooltip: {
      trigger: 'item'
      trigger: "item",
    },
    legend: {
      orient: 'vertical',
      top: 'center',
      icon: 'circle',
      orient: "vertical",
      top: "center",
      icon: "circle",
      itemWidth: 14,
      itemHeight: 14,
      right: '2%',
      right: "2%",
      itemGap: 10,
      textStyle: {
        align: 'left',
        verticalAlign: 'middle',
        align: "left",
        verticalAlign: "middle",
        rich: {
          name: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
          value: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
          rate: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
        },
      },
      formatter: (name) => {
        if (data.length) {
          let target, percent;
          let target, percent
          for (let i = 0; i < data.length; i++) {
            if (data[i].name === name) {
              target = data[i].value;
              percent = ((target / total) * 100).toFixed(2);
              target = data[i].value
              percent = ((target / total) * 100).toFixed(2)
            }
          }
          return `{name|${name}  }{value| ${target}} {rate| ${percent}%}`;
          return `{name|${name}  }{value| ${target}} {rate| ${percent}%}`
        } else {
          return `{name|${name}  }{value| ${0}} {rate| ${0}%}`;
          return `{name|${name}  }{value| ${0}} {rate| ${0}%}`
        }
      },
    },
    series: [{
    series: [
      {
      name,
      type: 'pie',
      radius: ['45%', '70%'],
      center: ['35%', '50%'],
        type: "pie",
        radius: ["45%", "70%"],
        center: ["35%", "50%"],
      avoidLabelOverlap: false,
      label: {
        show: false,
        overflow: 'none',
        formatter: '{b} {d}%  \n {c} tce',
          overflow: "none",
          formatter: "{b} {d}%  \n {c} tce",
      },
      data,
    }]
      },
    ],
  })
}
function getChart(Id, dataList) {
  const myChart3 = echarts.init(document.getElementById(Id));
  myChart3.setOption(
    {
  const myChart3 = echarts.init(document.getElementById(Id))
  myChart3.setOption({
      grid: {
        left: '3%',
        right: '2%',
        bottom: '2%',
        containLabel: true
      left: "3%",
      right: "2%",
      bottom: "2%",
      containLabel: true,
      },
      tooltip: {
        trigger: 'axis',
      trigger: "axis",
      },
      xAxis: {
        type: 'category',
      type: "category",
        // boundaryGap: false,
        data: dataList.xAxisData,
        axisPointer: {
          type: 'shadow'
        type: "shadow",
        },
        axisTick: {
          show: false,
          alignWithLabel: true,
          length: 5
        length: 5,
        },
        // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
        axisTick: {
          show: false,
          length: 5,
          lineStyle: {
            color: '#ddd'
          }
          color: "#ddd",
        },
        },
        // åˆ†å‰²çº¿
        splitLine: {
          show: false,
          lineStyle: {
            type: 'dashed',
            color: 'rgba(220,222,226,0.4)'
          }
          type: "dashed",
          color: "rgba(220,222,226,0.4)",
        },
        },
        axisLabel: {
          color: '#999',
        color: "#999",
          fontSize: 14,
          padding: [5, 0, 0, 0],
          //   formatter: '{value} ml'
        }
      },
      },
      yAxis: {
        type: 'value',
        name: '(次)',
      type: "value",
      name: "(次)",
        // è®¾ç½®åç§°æ ·å¼
        nameTextStyle: {
          color: ' #CEE3FF',
        color: " #CEE3FF",
          fontSize: 14,
          padding: [0, 0, 5, 0],
        },
@@ -283,24 +301,24 @@
        axisTick: {
          show: false,
          alignWithLabel: true,
          length: 5
        length: 5,
        },
        // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
        axisTick: {
          show: false,
          length: 5,
          lineStyle: {
            color: ''
          }
          color: "",
        },
        },
        // åˆ†å‰²çº¿
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed',
            color: 'rgba(220,222,226,0.4)'
          }
          type: "dashed",
          color: "rgba(220,222,226,0.4)",
        },
        },
        // åæ ‡è½´åˆ»åº¦é—´éš”
@@ -314,49 +332,48 @@
        // // åæ ‡è½´åˆ»åº¦æ–‡æœ¬çš„布局朝向
        // position: 'left'
        axisLabel: {
          color: '#B2B8C2',
        color: "#B2B8C2",
          fontSize: 14,
          //   formatter: '{value} ml'
        }
      },
      },
      series: [
        {
          name: "报警次数",
          type: "bar",
          barWidth: '17',
          stack: 'number',
        barWidth: "12",
        stack: "number",
          data: dataList.data,
          tooltip: {
            show: false,
          }
        },
        },
        {
          name: '报警次数',
          type: 'line',
          symbol: 'none', // è®¾ç½®ä¸º 'none' åŽ»æŽ‰åœ†ç‚¹
        name: "报警次数",
        type: "line",
        symbol: "none", // è®¾ç½®ä¸º 'none' åŽ»æŽ‰åœ†ç‚¹
          lineStyle: {
            color: '#EE0303'
          color: "#EE0303",
          },
          data: dataList.data,
        },
      ]
    ],
    })
  window.addEventListener("resize", () => {
    myChart1.resize();
    myChart2.resize();
    myChart3.resize();
  }, { passive: true });
  window.addEventListener(
    "resize",
    () => {
      myChart1.resize()
      myChart2.resize()
      myChart3.resize()
    },
    { passive: true }
  )
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.chart-box {
  height: calc((100vh - 410px)/2) !important;
zhitan-vue/src/views/alarmmanage/measuremen/measuremen.vue
@@ -8,16 +8,28 @@
        <div class="form-card">
          <el-form :model="form" ref="queryRef" :inline="true" label-width="85px">
            <el-form-item label="期间" prop="timeType">
              <el-select v-model="queryParams.timeType" placeholder="期间" clearable style="width: 120px"
                @change="handleTimeType">
              <el-select
                v-model="queryParams.timeType"
                placeholder="期间"
                clearable
                style="width: 120px"
                @change="handleTimeType"
              >
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
              <el-date-picker v-model="queryParams.dataTime" :clearable="false"
              <el-date-picker
                v-model="queryParams.dataTime"
                :clearable="false"
                :type="queryParams.timeType == 'YEAR' ? 'year' : queryParams.timeType == 'MONTH' ? 'month' : 'date'"
                :format="queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'"
                value-format="YYYY-MM-DD" placeholder="时间" style="width: 100%" />
                :format="
                  queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'
                "
                value-format="YYYY-MM-DD"
                placeholder="时间"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -27,8 +39,10 @@
        </div>
        <div class="mt20 mb20 text-center data-item">
          æœ¬ç”¨èƒ½å•元指标<span>{{ dataArray.indexCount }}</span>个,
          æœ¬å¹´åº¦æŠ¥è­¦<span>{{ dataArray.yearCount }}</span>次,本月<span>{{ dataArray.monthCount }}</span>次
          æœ¬ç”¨èƒ½å•元指标<span>{{ dataArray.indexCount }}</span
          >个, æœ¬å¹´åº¦æŠ¥è­¦<span>{{ dataArray.yearCount }}</span
          >次,本月<span>{{ dataArray.monthCount }}</span
          >次
        </div>
        <el-row :gutter="24" class="mb20">
          <el-col :span="12">
@@ -60,71 +74,70 @@
</template>
<script setup>
import * as echarts from 'echarts';
import { onMounted, reactive, ref } from 'vue';
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType";
const { proxy } = getCurrentInstance();
const { period } = proxy.useDict("period");
let { alarm_record_category } = proxy.useDict("alarm_record_category");
import * as echarts from "echarts"
import { onMounted, reactive, ref } from "vue"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
const { proxy } = getCurrentInstance()
const { period } = proxy.useDict("period")
let { alarm_record_category } = proxy.useDict("alarm_record_category")
let energyTypeList = ref([])
function getEnergyTypeList() {
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data;
    queryParams.value.energyType = energyTypeList.value[0].enersno;
  });
    energyTypeList.value = res.data
    queryParams.value.energyType = energyTypeList.value[0].enersno
  })
}
getEnergyTypeList()
function formatterLabel(list, value) {
  let dict = list.find(item => item.enersno == value)
  return dict ? dict.enername : ''
  let dict = list.find((item) => item.enersno == value)
  return dict ? dict.enername : ""
}
let queryParams = ref({
  timeType: null,
  dataTime: null,
  nodeId: null
  nodeId: null,
})
import { getByNodeId, getCountInfo } from "@/api/alarmManage/alarmManage";
import { el } from 'element-plus/es/locales.mjs';
let form = ref({});
import { getByNodeId, getCountInfo } from "@/api/alarmManage/alarmManage"
import { el } from "element-plus/es/locales.mjs"
let form = ref({})
let currentNode = ref()
function handleTimeType(e) {
  queryParams.value.timeType = e;
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD");
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
}
function handleNodeClick(e) {
  currentNode.value = e
  queryParams.value.nodeId = e.id
  handleTimeType(period.value[0].value);
  handleTimeType(period.value[0].value)
  getByNodeIdFun()
}
function getByNodeIdFun() {
  getByNodeId(queryParams.value).then(res => {
  getByNodeId(queryParams.value).then((res) => {
    let alarmList = []
    let energyList = []
    let alarmNumberList = {
      data: [],
      xAxisData: []
      xAxisData: [],
    }
    if (res.code == 200) {
      let { data } = res
      alarmList = data.alarmProportion.map(item => {
      alarmList = data.alarmProportion.map((item) => {
        return {
          name: proxy.selectDictLabel(alarm_record_category.value, item.energyName),
          value: item.count,
          percentage: item.percentage
          percentage: item.percentage,
        }
      })
      energyList = data.energyProportion.map(item => {
      energyList = data.energyProportion.map((item) => {
        return {
          name: formatterLabel(energyTypeList.value, item.energyName),
          value: item.count,
          percentage: item.percentage
          percentage: item.percentage,
        }
      })
      for (const item of data.chartDataList) {
@@ -132,9 +145,9 @@
        alarmNumberList.data.push(item.yvalue)
      }
      pieChart('Chart1', alarmList, '报警类型占比')
      pieChart('Chart2', energyList, '能源类型占比')
      getChart('Chart3', alarmNumberList)
      pieChart("Chart1", alarmList, "报警类型占比")
      pieChart("Chart2", energyList, "能源类型占比")
      getChart("Chart3", alarmNumberList)
    }
  })
}
@@ -144,16 +157,16 @@
  getByNodeIdFun()
}
function resetQuery() {
  handleTimeType('YEAR')
  handleTimeType("YEAR")
  getByNodeIdFun()
}
let dataArray = ref({
  indexCount: 0,
  yearCount: 0,
  monthCount: 0
  monthCount: 0,
})
function getCountInfoFun() {
  getCountInfo(queryParams.value).then(res => {
  getCountInfo(queryParams.value).then((res) => {
    if (res.code == 200) {
      dataArray.value = res.data
    }
@@ -163,45 +176,56 @@
getCountInfoFun()
function pieChart(Id, data, name) {
  console.log(data)
  let total = 0;
  let total = 0
  data.forEach(function (val, idx, arr) {
    total += val.value;
    total += val.value
  })
  const myChart = echarts.init(document.getElementById(Id));
  const myChart = echarts.init(document.getElementById(Id))
  myChart.setOption({
    color: ['#4D94FF', '#00C27C', '#F0142F', '#F2D261', '#0E7CE2', '#FF8352', '#E271DE', '#F8456B', '#00FFFF', '#4AEAB0'],
    color: [
      "#4D94FF",
      "#00C27C",
      "#F0142F",
      "#F2D261",
      "#0E7CE2",
      "#FF8352",
      "#E271DE",
      "#F8456B",
      "#00FFFF",
      "#4AEAB0",
    ],
    grid: {
      top: '20%',
      left: '1%',
      right: '1%',
      bottom: '0%',
      containLabel: true
      top: "20%",
      left: "1%",
      right: "1%",
      bottom: "0%",
      containLabel: true,
    },
    tooltip: {
      trigger: 'item'
      trigger: "item",
    },
    legend: {
      orient: 'vertical',
      top: 'center',
      icon: 'circle',
      orient: "vertical",
      top: "center",
      icon: "circle",
      itemWidth: 14,
      itemHeight: 14,
      right: '2%',
      right: "2%",
      itemGap: 10,
      textStyle: {
        align: 'left',
        verticalAlign: 'middle',
        align: "left",
        verticalAlign: "middle",
        rich: {
          name: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
          value: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
          rate: {
            color: '#999',
            color: "#999",
            fontSize: 14,
          },
        },
@@ -209,83 +233,82 @@
      formatter: (name) => {
        for (let i = 0; i < data.length; i++) {
          if (data[i].name === name) {
            return `{name|${data[i].name}  }{value| ${data[i].value}} {rate| ${data[i].percentage}%}`;
            return `{name|${data[i].name}  }{value| ${data[i].value}} {rate| ${data[i].percentage}%}`
          }
        }
      },
    },
    series: [{
    series: [
      {
      name,
      type: 'pie',
      radius: ['45%', '70%'],
      center: ['35%', '50%'],
        type: "pie",
        radius: ["45%", "70%"],
        center: ["35%", "50%"],
      avoidLabelOverlap: false,
      label: {
        show: false,
        overflow: 'none',
        formatter: '{b} {d}%  \n {c} tce',
          overflow: "none",
          formatter: "{b} {d}%  \n {c} tce",
      },
      data,
    }]
      },
    ],
  })
}
function getChart(Id, dataList) {
  const myChart3 = echarts.init(document.getElementById(Id));
  myChart3.setOption(
    {
  const myChart3 = echarts.init(document.getElementById(Id))
  myChart3.setOption({
      grid: {
        left: '3%',
        right: '2%',
        bottom: '2%',
        containLabel: true
      left: "3%",
      right: "2%",
      bottom: "2%",
      containLabel: true,
      },
      tooltip: {
        trigger: 'axis',
      trigger: "axis",
      },
      xAxis: {
        type: 'category',
      type: "category",
        // boundaryGap: false,
        data: dataList.xAxisData,
        axisPointer: {
          type: 'shadow'
        type: "shadow",
        },
        axisTick: {
          show: false,
          alignWithLabel: true,
          length: 5
        length: 5,
        },
        // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
        axisTick: {
          show: false,
          length: 5,
          lineStyle: {
            color: '#ddd'
          }
          color: "#ddd",
        },
        },
        // åˆ†å‰²çº¿
        splitLine: {
          show: false,
          lineStyle: {
            type: 'dashed',
            color: 'rgba(220,222,226,0.4)'
          }
          type: "dashed",
          color: "rgba(220,222,226,0.4)",
        },
        },
        axisLabel: {
          color: '#999',
        color: "#999",
          fontSize: 14,
          padding: [5, 0, 0, 0],
          //   formatter: '{value} ml'
        }
      },
      },
      yAxis: {
        type: 'value',
        name: '(次)',
      type: "value",
      name: "(次)",
        // è®¾ç½®åç§°æ ·å¼
        nameTextStyle: {
          color: ' #CEE3FF',
        color: " #CEE3FF",
          fontSize: 14,
          padding: [0, 0, 5, 0],
        },
@@ -293,24 +316,24 @@
        axisTick: {
          show: false,
          alignWithLabel: true,
          length: 5
        length: 5,
        },
        // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
        axisTick: {
          show: false,
          length: 5,
          lineStyle: {
            color: ''
          }
          color: "",
        },
        },
        // åˆ†å‰²çº¿
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed',
            color: 'rgba(220,222,226,0.4)'
          }
          type: "dashed",
          color: "rgba(220,222,226,0.4)",
        },
        },
        // åæ ‡è½´åˆ»åº¦é—´éš”
@@ -324,49 +347,48 @@
        // // åæ ‡è½´åˆ»åº¦æ–‡æœ¬çš„布局朝向
        // position: 'left'
        axisLabel: {
          color: '#B2B8C2',
        color: "#B2B8C2",
          fontSize: 14,
          //   formatter: '{value} ml'
        }
      },
      },
      series: [
        {
          name: "报警次数",
          type: "bar",
          barWidth: '17',
          stack: 'number',
        barWidth: "12",
        stack: "number",
          data: dataList.data,
          tooltip: {
            show: false,
          }
        },
        },
        {
          name: '报警次数',
          type: 'line',
          symbol: 'none', // è®¾ç½®ä¸º 'none' åŽ»æŽ‰åœ†ç‚¹
        name: "报警次数",
        type: "line",
        symbol: "none", // è®¾ç½®ä¸º 'none' åŽ»æŽ‰åœ†ç‚¹
          lineStyle: {
            color: '#EE0303'
          color: "#EE0303",
          },
          data: dataList.data,
        },
      ]
    ],
    })
  window.addEventListener("resize", () => {
    myChart1.resize();
    myChart2.resize();
    myChart3.resize();
  }, { passive: true });
  window.addEventListener(
    "resize",
    () => {
      myChart1.resize()
      myChart2.resize()
      myChart3.resize()
    },
    { passive: true }
  )
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.chart-box {
  height: calc((100vh - 410px)/2) !important;
@@ -378,7 +400,7 @@
  font-weight: bold;
  span {
    color: #397AEE;
    color: #397aee;
    margin: 0 5px;
  }
}
@@ -390,10 +412,9 @@
    font-weight: bold;
    span {
      color: #397AEE;
      color: #397aee;
      margin: 0 5px;
    }
  }
}
</style>
zhitan-vue/src/views/auxiliaryentry/electricityinput/electricityinput.vue
@@ -40,12 +40,12 @@
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <el-form-item style="float: right">
          <el-button type="primary" icon="Plus" @click="handleAdd"> æ–°å¢ž </el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="table-bg-style">
      <div class="theme-dark-mt20 mb20 ml20">
        <el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
      </div>
      <div class="table-box">
        <el-table :data="tableData" v-loading="loading">
          <el-table-column prop="time" label="时间" show-overflow-tooltip align="center" />
zhitan-vue/src/views/auxiliaryentry/productoutput/productOutput.vue
@@ -6,12 +6,7 @@
      </div>
      <div class="page-container-right">
        <div class="form-card">
          <el-form
            :model="queryParams"
            ref="queryRef"
            :inline="true"
            v-show="showSearch"
          >
          <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
            <el-form-item label="期间" prop="timeType">
              <el-select
                v-model="queryParams.timeType"
@@ -19,12 +14,7 @@
                style="width: 120px"
                @change="handleTimeType"
              >
                <el-option
                  v-for="dict in period"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
@@ -58,33 +48,20 @@
              />
            </el-form-item>
            <el-form-item label="产品类型">
              <el-select
                v-model="queryParams.productType"
                placeholder="产品类型"
                style="width: 100%"
              >
                <el-option
                  v-for="dict in product_type"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              <el-select v-model="queryParams.productType" placeholder="产品类型" style="width: 100%">
                <el-option v-for="dict in product_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">
                æœç´¢
              </el-button>
              <el-button type="primary" icon="Search" @click="handleQuery"> æœç´¢ </el-button>
              <el-button icon="Refresh" @click="resetQuery"> é‡ç½® </el-button>
            </el-form-item>
            <el-form-item style="float: right">
              <el-button type="primary" icon="Plus" @click="handleAdd"> æ–°å¢ž </el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="table-box">
          <div class="mt20 mb20">
            <el-button type="primary" icon="Plus" @click="handleAdd">
              æ–°å¢ž
            </el-button>
          </div>
          <el-table v-loading="loading" :data="productoutputList">
            <el-table-column
              label="用能单元"
@@ -93,13 +70,7 @@
              prop="nodeName"
              :show-overflow-tooltip="true"
            />
            <el-table-column
              label="期间"
              align="center"
              key="timeType"
              prop="timeType"
              :show-overflow-tooltip="true"
            >
            <el-table-column label="期间" align="center" key="timeType" prop="timeType" :show-overflow-tooltip="true">
              <template #default="scope">
                <dict-tag :options="period" :value="scope.row.timeType" />
              </template>
@@ -120,10 +91,7 @@
              :show-overflow-tooltip="true"
            >
              <template #default="scope">
                <dict-tag
                  :options="product_type"
                  :value="scope.row.productType"
                />
                <dict-tag :options="product_type" :value="scope.row.productType" />
              </template>
            </el-table-column>
            <!-- <el-table-column
@@ -133,24 +101,12 @@
              prop="name"
              :show-overflow-tooltip="true"
            /> -->
            <el-table-column
              label="单位"
              align="center"
              key="unit"
              prop="unit"
              :show-overflow-tooltip="true"
            >
            <el-table-column label="单位" align="center" key="unit" prop="unit" :show-overflow-tooltip="true">
              <template #default="scope">
                <dict-tag :options="sys_unit" :value="scope.row.unit" />
              </template>
            </el-table-column>
            <el-table-column
              label="产量"
              align="center"
              key="number"
              prop="number"
              :show-overflow-tooltip="true"
            />
            <el-table-column label="产量" align="center" key="number" prop="number" :show-overflow-tooltip="true" />
            <el-table-column
              label="提交时间"
              align="center"
@@ -158,32 +114,13 @@
              :show-overflow-tooltip="true"
              width="200"
            />
            <el-table-column
              label="操作"
              align="center"
              class-name="small-padding fixed-width"
              width="200"
            >
            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
              <template #default="scope">
                <el-tooltip content="编辑" placement="top">
                  <el-button
                    link
                    type="primary"
                    icon="Edit"
                    @click="handleUpdate(scope.row)"
                  >
                    ç¼–辑
                  </el-button>
                  <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"> ç¼–辑 </el-button>
                </el-tooltip>
                <el-tooltip content="删除" placement="top">
                  <el-button
                    link
                    type="primary"
                    icon="Delete"
                    @click="handleDelete(scope.row)"
                  >
                    åˆ é™¤
                  </el-button>
                  <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"> åˆ é™¤ </el-button>
                </el-tooltip>
              </template>
            </el-table-column>
@@ -203,11 +140,7 @@
        <el-row>
          <el-col :span="12">
            <el-form-item label="用能单元" prop="nodeName">
              <el-input
                v-model="form.nodeName"
                placeholder="请输入用能单元"
                disabled
              />
              <el-input v-model="form.nodeName" placeholder="请输入用能单元" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -219,12 +152,7 @@
                style="width: 100%"
                @change="handleTimeTypeAdd"
              >
                <el-option
                  v-for="dict in period"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -261,18 +189,8 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品类型" prop="productType">
              <el-select
                v-model="form.productType"
                placeholder="产品类型"
                clearable
                style="width: 100%"
              >
                <el-option
                  v-for="dict in product_type"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              <el-select v-model="form.productType" placeholder="产品类型" clearable style="width: 100%">
                <el-option v-for="dict in product_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -287,18 +205,8 @@
          </el-col> -->
          <el-col :span="12">
            <el-form-item label="单位" prop="unit">
              <el-select
                v-model="form.unit"
                placeholder="请选择单位"
                clearable
                style="width: 100%"
              >
                <el-option
                  v-for="dict in sys_unit"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              <el-select v-model="form.unit" placeholder="请选择单位" clearable style="width: 100%">
                <el-option v-for="dict in sys_unit" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -331,19 +239,15 @@
  addProductoutput,
  updateProductoutput,
  delProductoutput,
} from "@/api/auxiliaryEntry/productOutput";
const { proxy } = getCurrentInstance();
import { useRoute } from "vue-router";
const { period, sys_unit, product_type } = proxy.useDict(
  "period",
  "sys_unit",
  "product_type"
);
const productoutputList = ref([]);
const open = ref(false);
const loading = ref(false);
const showSearch = ref(true);
const title = ref("");
} from "@/api/auxiliaryEntry/productOutput"
const { proxy } = getCurrentInstance()
import { useRoute } from "vue-router"
const { period, sys_unit, product_type } = proxy.useDict("period", "sys_unit", "product_type")
const productoutputList = ref([])
const open = ref(false)
const loading = ref(false)
const showSearch = ref(true)
const title = ref("")
const data = reactive({
  form: {},
  queryParams: {
@@ -358,12 +262,8 @@
  },
  query: { ...useRoute().query },
  rules: {
    timeType: [
      { required: true, message: "期间不能为空", trigger: ["blur", "change"] },
    ],
    dataTime: [
      { required: true, message: "时间不能为空", trigger: ["blur", "change"] },
    ],
    timeType: [{ required: true, message: "期间不能为空", trigger: ["blur", "change"] }],
    dataTime: [{ required: true, message: "时间不能为空", trigger: ["blur", "change"] }],
    productType: [
      {
        required: true,
@@ -373,78 +273,74 @@
    ],
    // name: [{ required: true, message: "产品名称不能为空", trigger: "blur" }],
    unit: [{ required: true, message: "单位不能为空", trigger: "blur" }],
    number: [
      { required: true, message: "产量不能为空", trigger: ["blur", "change"] },
    ],
    number: [{ required: true, message: "产量不能为空", trigger: ["blur", "change"] }],
  },
});
const { queryParams, query, form, rules } = toRefs(data);
})
const { queryParams, query, form, rules } = toRefs(data)
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id;
  queryParams.value.nodeName = data.label;
  queryParams.value.productType = null;
  handleTimeType(period.value[0].value);
  handleQuery();
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  queryParams.value.productType = null
  handleTimeType(period.value[0].value)
  handleQuery()
}
function handleTimeType(e) {
  queryParams.value.timeType = e;
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy
    .dayjs(new Date())
    .format(e == "YEAR" ? "YYYY" : e == "MONTH" ? "YYYY-MM" : "YYYY-MM-DD");
    .format(e == "YEAR" ? "YYYY" : e == "MONTH" ? "YYYY-MM" : "YYYY-MM-DD")
}
// è¾…助录入-产品产量录入-列表
function getList() {
  loading.value = true;
  loading.value = true
  listProductoutput(
    proxy.addDateRange({
      ...queryParams.value,
      ...query.value,
    })
  ).then((res) => {
    loading.value = false;
    productoutputList.value = res.rows;
    queryParams.value.total = res.total;
  });
    loading.value = false
    productoutputList.value = res.rows
    queryParams.value.total = res.total
  })
}
// è¾…助录入-产品产量录入-搜索
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
  queryParams.value.pageNum = 1
  getList()
}
// è¾…助录入-产品产量录入-重置
function resetQuery() {
  proxy.resetForm("queryRef");
  queryParams.value.pageNum = 1;
  queryParams.value.pageSize = 10;
  queryParams.value.total = 0;
  queryParams.value.timeType = null;
  queryParams.value.dataTime = null;
  queryParams.value.productType = null;
  handleTimeType(period.value[0].value);
  handleQuery();
  proxy.resetForm("queryRef")
  queryParams.value.pageNum = 1
  queryParams.value.pageSize = 10
  queryParams.value.total = 0
  queryParams.value.timeType = null
  queryParams.value.dataTime = null
  queryParams.value.productType = null
  handleTimeType(period.value[0].value)
  handleQuery()
}
// è¾…助录入-产品产量录入-新增
function handleAdd() {
  reset();
  form.value.nodeId = queryParams.value.nodeId;
  form.value.nodeName = queryParams.value.nodeName;
  handleTimeTypeAdd(period.value[0].value);
  title.value = "新增产品产量录入";
  open.value = true;
  reset()
  form.value.nodeId = queryParams.value.nodeId
  form.value.nodeName = queryParams.value.nodeName
  handleTimeTypeAdd(period.value[0].value)
  title.value = "新增产品产量录入"
  open.value = true
}
function handleTimeTypeAdd(e) {
  form.value.timeType = e;
  form.value.dataTime = proxy
    .dayjs(new Date())
    .format(e == "YEAR" ? "YYYY" : e == "MONTH" ? "YYYY-MM" : "YYYY-MM-DD");
  form.value.timeType = e
  form.value.dataTime = proxy.dayjs(new Date()).format(e == "YEAR" ? "YYYY" : e == "MONTH" ? "YYYY-MM" : "YYYY-MM-DD")
}
// è¾…助录入-产品产量录入-编辑
function handleUpdate(row) {
  reset();
  form.value = { ...row };
  open.value = true;
  title.value = "编辑产品产量录入";
  reset()
  form.value = { ...row }
  open.value = true
  title.value = "编辑产品产量录入"
}
// è¾…助录入-产品产量录入-新增/编辑-保存
function submitForm() {
@@ -452,24 +348,24 @@
    if (valid) {
      if (form.value.productOutputId != undefined) {
        updateProductoutput(form.value).then((response) => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getList();
        });
          proxy.$modal.msgSuccess("修改成功")
          open.value = false
          getList()
        })
      } else {
        addProductoutput(form.value).then((response) => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getList();
        });
          proxy.$modal.msgSuccess("新增成功")
          open.value = false
          getList()
        })
      }
    }
  });
  })
}
// è¾…助录入-产品产量录入-新增/编辑-取消
function cancel() {
  open.value = false;
  reset();
  open.value = false
  reset()
}
// è¾…助录入-产品产量录入-新增/编辑-表单重置
function reset() {
@@ -480,8 +376,8 @@
    number: "1",
    timeType: "",
    unit: "",
  };
  proxy.resetForm("formRef");
  }
  proxy.resetForm("formRef")
}
// è¾…助录入-产品产量录入-删除
function handleDelete(row) {
@@ -489,13 +385,13 @@
    .confirm('是否确认删除时间为"' + row.dataTime + '"的数据项?')
    // .confirm('是否确认删除产品名称为"' + row.name + '"的数据项?')
    .then(function () {
      return delProductoutput(row.productOutputId);
      return delProductoutput(row.productOutputId)
    })
    .then(() => {
      getList();
      proxy.$modal.msgSuccess("删除成功");
      getList()
      proxy.$modal.msgSuccess("删除成功")
    })
    .catch(() => {});
    .catch(() => {})
}
</script>
<style scoped lang="scss">
zhitan-vue/src/views/buildingConsumption/branch-build/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,306 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" />
      </div>
      <div class="page-container-right">
        <div class="form-card">
          <el-form :model="queryParams" ref="queryRef" :inline="true">
            <el-form-item label="期间" prop="timeType">
              <el-select
                v-model="queryParams.timeType"
                placeholder="期间"
                clearable
                style="width: 120px"
                @change="handleTimeType"
              >
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
              <el-date-picker
                v-model="queryParams.dataTime"
                :type="queryParams.timeType == 'YEAR' ? 'year' : queryParams.timeType == 'MONTH' ? 'month' : 'date'"
                :format="
                  queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'
                "
                value-format="YYYY-MM-DD"
                placeholder="时间"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item label="能源类型" prop="energyType">
              <el-select v-model="queryParams.energyType" placeholder="能源类型" style="width: 120px">
                <el-option
                  :label="item.enername"
                  :value="item.enersno"
                  v-for="item in energyTypeList"
                  :key="item.enersno"
                  @click="handleEnergyType(item)"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery"> æœç´¢ </el-button>
              <!-- <el-button icon="Refresh" @click="resetQuery">重置</el-button> -->
            </el-form-item>
            <!-- <el-form-item>
              <el-button type="warning" icon="Download" @click="handleExport"> å¯¼å‡º </el-button>
            </el-form-item> -->
          </el-form>
        </div>
        <div
          style="height: calc(100vh - 220px) !important; max-height: calc(100vh - 220px) !important; overflow-y: auto"
          v-loading="loading"
        >
          <BaseCard :title="queryParams.nodeName + '-支路用能分析'">
            <div class="">
              <!-- <div id="Chart1" /> -->
              <line-chart ref="LineChartRef" :chartData="lineChartData" :chartType="'bar'" />
            </div>
          </BaseCard>
          <BaseCard :title="queryParams.nodeName + '-支路用能详情-' + queryParams.enername">
            <div class="table-box">
              <!-- show-summary -->
              <el-table :data="departmentList">
                <el-table-column label="节点" align="center" key="nodeName" prop="nodeName" fixed="left" />
                <el-table-column label="合计" align="center" key="total" prop="total" width="100" fixed="left" />
                <template v-if="queryParams.timeType == 'DAY'">
                  <el-table-column
                    v-for="index in 24"
                    :key="index"
                    :label="index - 1 + '时'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
                <template v-if="queryParams.timeType == 'MONTH'">
                  <el-table-column
                    v-for="index in 31"
                    :key="index"
                    :label="index + '日'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
                <template v-if="queryParams.timeType == 'YEAR'">
                  <el-table-column
                    v-for="index in 12"
                    :key="index"
                    :label="index + '月'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
              </el-table>
            </div>
          </BaseCard>
          <!-- </el-col>
          </el-row> -->
        </div>
      </div>
    </div>
  </div>
</template>
<script setup name="branchanalysis">
import buildApi from "@/api/buildingConsumption/api"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import LineChart from "@/components/Echarts/LineChart.vue"
const { proxy } = getCurrentInstance()
const { period } = proxy.useDict("period")
import { useRoute } from "vue-router"
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
watch(
  () => settingsStore.sideTheme,
  (val) => {
    getList()
  }
)
const energyTypeList = ref(undefined)
const departmentList = ref([])
const loading = ref(false)
const data = reactive({
  queryParams: {
    nodeId: null,
    timeType: null,
    dataTime: null,
    energyType: null,
  },
  query: {
    modelCode: null,
  },
})
const { queryParams, query } = toRefs(data)
const itemBuildData = ref({})
const LineChartRef = ref()
const lineChartData = ref({})
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  handleTimeType(period.value[0].value)
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    queryParams.value.energyType = energyTypeList.value[0].enersno
    queryParams.value.enername = energyTypeList.value[0].enername
    queryParams.value.muid = energyTypeList.value[0].muid
    handleQuery()
  })
}
function handleTimeType(e) {
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  handleQuery()
}
function handleEnergyType(item) {
  queryParams.value.enername = item.enername
  queryParams.value.muid = item.muid
  handleQuery()
}
function getList() {
  loading.value = true
  buildApi
    .branchanalysis(
      proxy.addDateRange({
        ...queryParams.value,
        ...query.value,
      })
    )
    .then((res) => {
      if (!!res.code && res.code == 200) {
        loading.value = false
        let yData = []
        let xData = []
        if (!!res.data) {
          departmentList.value = [res.data] || []
        }
        let dataList = res.data || {}
        if (queryParams.value.timeType == "DAY") {
          for (let i = 0; i < 24; i++) {
            xData.push(i + "时")
            yData.push(dataList[`value${i}`])
          }
        } else if (queryParams.value.timeType == "MONTH") {
          for (let i = 0; i < 31; i++) {
            xData.push(i + 1 + "日")
            yData.push(dataList[`value${i}`])
          }
        } else {
          for (let i = 0; i < 12; i++) {
            xData.push(i + 1 + "月")
            yData.push(dataList[`value${i}`])
          }
        }
        lineChartData.value = {
          title: queryParams.value.muid,
          xAxis: xData,
          series: [
            {
              name: queryParams.value.enername,
              data: yData,
            },
          ],
        }
      }
    })
    .catch(() => {
      loading.value = false
    })
}
function numFilter(value) {
  // æˆªå–当前数据到小数点后的几位
  let realVal = ""
  if (!isNaN(value) && value !== "" && value !== null) {
    realVal = parseFloat(value).toFixed(2)
  } else {
    realVal = "--"
  }
  return realVal
}
// èƒ½è€—对比分析-科室能耗分析-搜索
function handleQuery() {
  getList()
}
// èƒ½è€—对比分析-科室能耗分析-重置
function resetQuery() {
  proxy.resetForm("queryRef")
  handleTimeType(period.value[0].value)
  queryParams.value.energyType = energyTypeList.value[0].enersno
  queryParams.value.enername = energyTypeList.value[0].enername
  queryParams.value.muid = energyTypeList.value[0].muid
  queryParams.value.analysisType = "YOY"
  handleQuery()
}
// èƒ½è€—对比分析-科室能耗分析-导出
function handleExport() {
  proxy.download(
    "consumptionanalysis/energyExport",
    {
      ...queryParams.value,
      ...query.value,
    },
    `${queryParams.value.nodeName}-厂区能耗分析_${new Date().getTime()}.xlsx`
  )
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.el-tabs {
  padding: 0 12px;
  margin-top: 12px;
  :deep(.el-tabs__header) {
    margin: 0;
  }
}
.themeDark {
  .build-sum {
    border: 1px solid #8c8b8b;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    .build-sum-item {
      width: 25%;
      text-align: center;
      padding: 12px 0;
      .count {
        font-size: 24px;
        font-weight: 600;
        margin-top: 8px;
        color: #409eff;
      }
    }
  }
}
.themeLight {
  .build-sum {
    border: 1px solid #eaeaea;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #333;
    .build-sum-item {
      width: 25%;
      text-align: center;
      padding: 12px 0;
      .count {
        font-size: 24px;
        font-weight: 600;
        margin-top: 8px;
        color: #409eff;
      }
    }
  }
}
</style>
zhitan-vue/src/views/buildingConsumption/item-build/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,326 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" />
      </div>
      <div class="page-container-right">
        <div class="form-card">
          <el-form :model="queryParams" ref="queryRef" :inline="true">
            <el-form-item label="期间" prop="timeType">
              <el-select
                v-model="queryParams.timeType"
                placeholder="期间"
                clearable
                style="width: 120px"
                @change="handleTimeType"
              >
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
              <el-date-picker
                v-model="queryParams.dataTime"
                :type="queryParams.timeType == 'YEAR' ? 'year' : queryParams.timeType == 'MONTH' ? 'month' : 'date'"
                :format="
                  queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'
                "
                value-format="YYYY-MM-DD"
                placeholder="时间"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item label="能源类型" prop="energyType">
              <el-select v-model="queryParams.energyType" placeholder="能源类型" style="width: 120px">
                <el-option
                  :label="item.enername"
                  :value="item.enersno"
                  v-for="item in energyTypeList"
                  :key="item.enersno"
                  @click="handleEnergyType(item)"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery"> æœç´¢ </el-button>
              <!-- <el-button icon="Refresh" @click="resetQuery">重置</el-button> -->
            </el-form-item>
            <!-- <el-form-item>
              <el-button type="warning" icon="Download" @click="handleExport"> å¯¼å‡º </el-button>
            </el-form-item> -->
          </el-form>
        </div>
        <div
          style="height: calc(100vh - 220px) !important; max-height: calc(100vh - 220px) !important; overflow-y: auto"
          v-loading="loading"
        >
          <BaseCard :title="queryParams.nodeName + '-分项用能分析'">
            <div class="build-sum">
              <div class="build-sum-item">
                <div>总用量/{{ queryParams.muid }}</div>
                <div class="count">{{ itemBuildData.total || 0 }}</div>
              </div>
              <div class="build-sum-item">
                <div>最大用量/{{ queryParams.muid }}</div>
                <div class="count">{{ itemBuildData.max || 0 }}</div>
              </div>
              <div class="build-sum-item">
                <div>最小用量/{{ queryParams.muid }}</div>
                <div class="count">{{ itemBuildData.min || 0 }}</div>
              </div>
              <div class="build-sum-item">
                <div>平均用量/{{ queryParams.muid }}</div>
                <div class="count">{{ itemBuildData.avg || 0 }}</div>
              </div>
            </div>
            <div class="">
              <!-- <div id="Chart1" /> -->
              <line-chart ref="LineChartRef" :chartData="lineChartData" />
            </div>
          </BaseCard>
          <BaseCard :title="queryParams.nodeName + '-分项用能详情-' + queryParams.enername">
            <div class="table-box">
              <!-- show-summary -->
              <el-table :data="departmentList">
                <el-table-column label="节点" align="center" key="nodeName" prop="nodeName" fixed="left" />
                <el-table-column label="合计" align="center" key="total" prop="total" width="100" fixed="left" />
                <template v-if="queryParams.timeType == 'DAY'">
                  <el-table-column
                    v-for="index in 24"
                    :key="index"
                    :label="index - 1 + '时'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
                <template v-if="queryParams.timeType == 'MONTH'">
                  <el-table-column
                    v-for="index in 31"
                    :key="index"
                    :label="index + '日'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
                <template v-if="queryParams.timeType == 'YEAR'">
                  <el-table-column
                    v-for="index in 12"
                    :key="index"
                    :label="index + '月'"
                    align="center"
                    min-width="130"
                  >
                    <template #default="scope">{{ scope.row[`value${index - 1}`] }}</template>
                  </el-table-column>
                </template>
              </el-table>
            </div>
          </BaseCard>
          <!-- </el-col>
          </el-row> -->
        </div>
      </div>
    </div>
  </div>
</template>
<script setup name="itemBuild">
import buildApi from "@/api/buildingConsumption/api"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import LineChart from "@/components/Echarts/LineChart.vue"
const { proxy } = getCurrentInstance()
const { period } = proxy.useDict("period")
import { useRoute } from "vue-router"
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
watch(
  () => settingsStore.sideTheme,
  (val) => {
    getList()
  }
)
const energyTypeList = ref(undefined)
const departmentList = ref([])
const loading = ref(false)
const data = reactive({
  queryParams: {
    nodeId: null,
    timeType: null,
    dataTime: null,
    energyType: null,
  },
  query: {
    modelCode: null,
  },
})
const { queryParams, query } = toRefs(data)
const itemBuildData = ref({})
const LineChartRef = ref()
const lineChartData = ref({})
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  handleTimeType(period.value[0].value)
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    queryParams.value.energyType = energyTypeList.value[0].enersno
    queryParams.value.enername = energyTypeList.value[0].enername
    queryParams.value.muid = energyTypeList.value[0].muid
    handleQuery()
  })
}
function handleTimeType(e) {
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  handleQuery()
}
function handleEnergyType(item) {
  queryParams.value.enername = item.enername
  queryParams.value.muid = item.muid
  handleQuery()
}
function getList() {
  loading.value = true
  buildApi
    .itemizedEnergyAnalysis(
      proxy.addDateRange({
        ...queryParams.value,
        ...query.value,
      })
    )
    .then((res) => {
      if (!!res.code && res.code == 200) {
        loading.value = false
        itemBuildData.value = res.data
        let yData = []
        let xData = []
        let title = []
        if (!!res.data.dataList) {
          departmentList.value = res.data.dataList || []
        }
        let dataList = res.data.dataList || []
        if (queryParams.value.timeType == "DAY") {
          for (let i = 0; i < 24; i++) {
            xData.push(i + "时")
            yData.push(dataList[0][`value${i}`])
          }
        } else if (queryParams.value.timeType == "MONTH") {
          for (let i = 0; i < 31; i++) {
            xData.push(i + 1 + "日")
            yData.push(dataList[0][`value${i}`])
          }
        } else {
          for (let i = 0; i < 12; i++) {
            xData.push(i + 1 + "月")
            yData.push(dataList[0][`value${i}`])
          }
        }
        lineChartData.value = {
          title: queryParams.value.muid,
          xAxis: xData,
          series: [
            {
              name: queryParams.value.enername,
              data: yData,
            },
          ],
        }
      }
    })
    .catch(() => {
      loading.value = false
    })
}
function numFilter(value) {
  // æˆªå–当前数据到小数点后的几位
  let realVal = ""
  if (!isNaN(value) && value !== "" && value !== null) {
    realVal = parseFloat(value).toFixed(2)
  } else {
    realVal = "--"
  }
  return realVal
}
// èƒ½è€—对比分析-科室能耗分析-搜索
function handleQuery() {
  getList()
}
// èƒ½è€—对比分析-科室能耗分析-重置
function resetQuery() {
  proxy.resetForm("queryRef")
  handleTimeType(period.value[0].value)
  queryParams.value.energyType = energyTypeList.value[0].enersno
  queryParams.value.enername = energyTypeList.value[0].enername
  queryParams.value.muid = energyTypeList.value[0].muid
  queryParams.value.analysisType = "YOY"
  handleQuery()
}
// èƒ½è€—对比分析-科室能耗分析-导出
function handleExport() {
  proxy.download(
    "consumptionanalysis/energyExport",
    {
      ...queryParams.value,
      ...query.value,
    },
    `${queryParams.value.nodeName}-厂区能耗分析_${new Date().getTime()}.xlsx`
  )
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.el-tabs {
  padding: 0 12px;
  margin-top: 12px;
  :deep(.el-tabs__header) {
    margin: 0;
  }
}
.themeDark {
  .build-sum {
    border: 1px solid #8c8b8b;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    .build-sum-item {
      width: 25%;
      text-align: center;
      padding: 12px 0;
      .count {
        font-size: 24px;
        font-weight: 600;
        margin-top: 8px;
        color: #409eff;
      }
    }
  }
}
.themeLight {
  .build-sum {
    border: 1px solid #eaeaea;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #333;
    .build-sum-item {
      width: 25%;
      text-align: center;
      padding: 12px 0;
      .count {
        font-size: 24px;
        font-weight: 600;
        margin-top: 8px;
        color: #409eff;
      }
    }
  }
}
</style>
zhitan-vue/src/views/businessconfiguration/alarmmaintenance/alarmMaintenance.vue
@@ -9,14 +9,13 @@
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <el-form-item style="float: right">
          <el-button type="primary" icon="plus" @click="handleAdd">新增</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="table-bg-style">
      <div class="theme-dark-mt20 mb20 ml20">
        <el-button type="primary" icon="plus" @click="handleAdd">新增</el-button>
        <!-- <el-button type="primary" icon="Delete">删除</el-button> -->
      </div>
      <div class="table-box">
        <el-table :data="tableData" v-loading="loading">
          <el-table-column prop="limitName" label="限值类型名称" show-overflow-tooltip align="center" />
zhitan-vue/src/views/businessconfiguration/gatewayledger/gatewayLedger.vue
@@ -3,21 +3,22 @@
        <div class="form-card">
            <el-form :inline="true">
                <el-form-item label="网关数量:" class="header-box">
                    {{ total }}
          <span class="count">{{ total || 0 }}</span>
                </el-form-item>
                <el-form-item label="计量器具数量:" class="header-box">
                    {{ statistics.deviceNum }}
          <span class="count">{{ deviceNum || 0 }}</span>
                </el-form-item>
                <el-form-item label="测点数量:" class="header-box">
                    {{ statistics.ptNum }}
          <span class="count">{{ ptNum || 0 }}</span>
                </el-form-item>
            </el-form>
        </div>
        <div class="table-box">
            <div class="mt20 mb20">
        <div class="mb20 ml20 mr20" style="float: right">
                <el-button type="primary" icon="plus" @click="handleAdd">新增</el-button>
                <el-button type="primary" icon="Download" @click="handleExport">导出</el-button>
            </div>
      </el-form>
    </div>
    <div class="table-bg-style">
      <div class="table-box">
            <el-table :data="tableData" v-loading="loading">
                <el-table-column prop="gatewayNum" label="网关编号" show-overflow-tooltip align="center" />
                <el-table-column prop="gatewayName" label="网关名称" show-overflow-tooltip align="center" />
@@ -29,33 +30,36 @@
                <el-table-column prop="ptNum" label="采集测点数量" show-overflow-tooltip align="center" />
                <el-table-column label="操作" width="300" align="center">
                    <template #default="scope">
                        <el-button link type="primary" icon="Edit" @click="handleAdd(scope.row)">
                            ä¿®æ”¹
                        </el-button>
                        <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">
                            åˆ é™¤
                        </el-button>
              <el-button link type="primary" icon="Edit" @click="handleAdd(scope.row)"> ä¿®æ”¹ </el-button>
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"> åˆ é™¤ </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
                v-model:limit="queryParams.pageSize" @pagination="getList" />
        <pagination
          v-show="total > 0"
          :total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="getList"
        />
        </div>
    </div>
        <edit-modal ref="EditModalRef" @getList="getList(1)" />
    </div>
</template>
<script setup>
import EditModal from './components/EditModal.vue'
import { gatewayStatistics, gatewayList, gatewayDel } from "@/api/businessConfiguration/gatewayLedger";
import EditModal from "./components/EditModal.vue"
import { gatewayStatistics, gatewayList, gatewayDel } from "@/api/businessConfiguration/gatewayLedger"
let { proxy } = getCurrentInstance()
let statistics = ref({
    deviceNum: 0,
    ptNum: 0
  ptNum: 0,
})
function getGatewayStatisticsFun() {
    gatewayStatistics().then(res => {
  gatewayStatistics().then((res) => {
        if (res.code == 200) {
            if (res.data) {
                statistics.value = res.data
@@ -65,9 +69,8 @@
}
getGatewayStatisticsFun()
let loading = ref(false);
let total = ref(0);
let loading = ref(false)
let total = ref(0)
let tableData = ref([])
let queryParams = ref({
    pageNum: 1,
@@ -79,7 +82,7 @@
        queryParams.value.pageNum = 1
    }
    loading.value = true
    gatewayList(queryParams.value).then(res => {
  gatewayList(queryParams.value).then((res) => {
        tableData.value = res.rows
        total.value = res.total
        loading.value = false
@@ -88,44 +91,49 @@
getList()
function handleExport() {
    proxy.download(
        "gatewaySetting/export",
        queryParams.value,
        `网关台账${new Date().getTime()}.xlsx`
    );
  proxy.download("gatewaySetting/export", queryParams.value, `网关台账${new Date().getTime()}.xlsx`)
}
let EditModalRef = ref('')
let EditModalRef = ref("")
function handleAdd(row) {
    if (EditModalRef.value) {
        EditModalRef.value.handleOpen(row)
    }
}
function handleDelete(row) {
    proxy.$modal
        .confirm('是否确认删除网关为"' + row.gatewayName + '"的数据项?')
        .then(function () {
            return gatewayDel(row.id);
      return gatewayDel(row.id)
        })
        .then(() => {
            getList(1);
            proxy.$modal.msgSuccess("删除成功");
      getList(1)
      proxy.$modal.msgSuccess("删除成功")
        })
        .catch(() => { });
    .catch(() => {})
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
.header-box {
    :deep .el-form-item__content {
        color: #fff;
        font-size: 16px;
    }
}
.themeDark {
  .count {
    color: #fff;
  }
}
.themeLight {
  .count {
    color: #333;
  }
}
</style>
zhitan-vue/src/views/businessconfiguration/gatewaystatus/gatewayStatus.vue
@@ -1,5 +1,11 @@
<template>
  <div class="page">
    <div class="page-title">
      <div class="title-bar">
        <span class="title-text">网关状态监测</span>
      </div>
    </div>
    <div class="table-box">
      <div class="border">
        <div class="table" v-for="(item, index) in dataList" :key="index">
@@ -460,14 +466,62 @@
])
</script>
<style lang="scss" scoped>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.page {
  background: #08234F;
  min-height: calc(100vh - 145px)
}
.page-title {
  position: relative;
  .title-bar {
    position: relative;
    padding: 14px 0;
    padding-left: 16px;
    .title-text {
      font-size: 18px;
      font-weight: 600;
      position: relative;
      padding-left: 22px;
      color: #fff;
      &::before {
        content: '';
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 5px;
        height: 18px;
        background-color: #3883FA;
        border-radius: 2px;
      }
    }
  }
  &::after {
    content: '';
    position: absolute;
    bottom: -4px;
    opacity: 0.12;
    left: 0;
    width: 100%;
    height: 1px;
    background-color: #E6E6E6;
  }
}
.themeDark {
  .border {
    border: 1px solid #fff;
    color: #fff;
    .table {
      margin-top: 10px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
@@ -544,6 +598,10 @@
        }
      }
    }
  }
  .table-box {
    margin: 20px 25px;
  }
}
@@ -630,5 +688,15 @@
      }
    }
  }
  .table-box {
    margin: 10px 25px;
  }
}
.page {
  .table-box {
    // ... ä¿æŒçŽ°æœ‰æ ·å¼
  }
}
</style>
zhitan-vue/src/views/businessconfiguration/prealarmmanage/components/collectionpointmanage/CollectionPointManage.vue
@@ -1,6 +1,6 @@
<template>
  <div class="table-box">
    <div class="form-card">
    <div class="form-card" style="padding: 16px 16px 0 16px">
      <el-form :model="queryParams" ref="queryRef" :inline="true">
        <el-form-item label="采集点名称">
          <el-input v-model="queryParams.name" placeholder="请输入采集点名称" maxlength="30" />
@@ -9,9 +9,7 @@
          <el-input v-model="queryParams.code" placeholder="请输入采集点编码" maxlength="30" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="getTabList">
            æœç´¢
          </el-button>
          <el-button type="primary" icon="Search" @click="getTabList"> æœç´¢ </el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <el-form-item>
@@ -24,28 +22,37 @@
        </el-form-item>
      </el-form>
    </div>
    <el-table v-loading="loading" row-key="indexId" :data="tableData" @selection-change="handleSelectionChange"
      height="calc(100vh - 430px)" :default-sort="{ prop: 'date', order: 'descending' }">
    <el-table
      v-loading="loading"
      row-key="indexId"
      :data="tableData"
      @selection-change="handleSelectionChange"
      height="calc(100vh - 430px)"
      :default-sort="{ prop: 'date', order: 'descending' }"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="采集点名称" align="center" prop="name" />
      <el-table-column label="采集点编码" align="center" prop="code" />
      <el-table-column label="启停状态" align="center" prop="indexCategory" />
      <el-table-column label="操作" width="150" align="center">
        <template #default="scope">
          <el-button link type="primary" @click="handleAlarm(scope.row)">
            æŠ¥è­¦
          </el-button>
          <el-button link type="primary" @click="handleAlarm(scope.row)"> æŠ¥è­¦ </el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="queryParams.total > 0" :total="queryParams.total" v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize" @pagination="getTabList" />
    <pagination
      v-show="queryParams.total > 0"
      :total="queryParams.total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getTabList"
    />
    <CollectAlarmModal ref="collectAlarmModalRef" />
  </div>
</template>
<script setup>
import CollectAlarmModal from './CollectAlarmModal.vue'
import { getSettingIndex, getStartStop, getSettingCount, updateSet } from '@/api/businessConfiguration/preAlarmManage'
import CollectAlarmModal from "./CollectAlarmModal.vue"
import { getSettingIndex, getStartStop, getSettingCount, updateSet } from "@/api/businessConfiguration/preAlarmManage"
let { proxy } = getCurrentInstance()
const data = reactive({
@@ -57,8 +64,8 @@
    pageSize: 10,
    total: 0,
  },
});
const { queryParams } = toRefs(data);
})
const { queryParams } = toRefs(data)
let ids = ref([])
let names = ref([])
let single = ref(true)
@@ -73,41 +80,40 @@
function getList(modelNode) {
  currentNode.value = modelNode
  queryParams.value.nodeId = modelNode.id
  queryParams.value.indexType = 'COLLECT',
    getTabList()
  ;(queryParams.value.indexType = "COLLECT"), getTabList()
}
function getTabList() {
  loading.value = true;
  getSettingIndex(queryParams.value).then(res => {
    tableData.value = res.data.records;
  loading.value = true
  getSettingIndex(queryParams.value).then((res) => {
    tableData.value = res.data.records
    queryParams.value.total = res.data.total
    loading.value = false;
    loading.value = false
    initStartStop()
  })
}
function resetQuery() {
  proxy.resetForm("queryRef");
  queryParams.value.code = null;
  queryParams.value.name = null;
  queryParams.value.pageNum = 1;
  queryParams.value.pageSize = 10;
  queryParams.value.total = 0;
  getTabList();
  proxy.resetForm("queryRef")
  queryParams.value.code = null
  queryParams.value.name = null
  queryParams.value.pageNum = 1
  queryParams.value.pageSize = 10
  queryParams.value.total = 0
  getTabList()
}
function initStartStop() {
  for (let i = 0; i < tableData.value.length; i++) {
    let ndy = ''
    getStartStop(tableData.value[i].indexId).then(response => {
      if (response.code == '200') {
        if (response.msg == '1') {
          tableData.value[i].indexCategory = '启动'
        } else if (response.msg == '2') {
          tableData.value[i].indexCategory = '停止'
    let ndy = ""
    getStartStop(tableData.value[i].indexId).then((response) => {
      if (response.code == "200") {
        if (response.msg == "1") {
          tableData.value[i].indexCategory = "启动"
        } else if (response.msg == "2") {
          tableData.value[i].indexCategory = "停止"
        } else {
          tableData.value[i].indexCategory = '尚未设置'
          tableData.value[i].indexCategory = "尚未设置"
        }
      } else {
        tableData.value[i].indexCategory = ''
        tableData.value[i].indexCategory = ""
      }
    })
  }
@@ -120,22 +126,22 @@
// å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.indexId)
  names.value = selection.map(item => item.name)
  ids.value = selection.map((item) => item.indexId)
  names.value = selection.map((item) => item.name)
  single.value = selection.length !== 1
  multiple.value = !selection.length
  startStopOptions.value = selection.map(item => item.indexCategory)
  codeOptions.value = selection.map(item => item.code)
  startStopOptions.value = selection.map((item) => item.indexCategory)
  codeOptions.value = selection.map((item) => item.code)
}
function handleUpdateState(flag) {
  let stateName = ''
  if (flag == '1') {
    stateName = '启动'
  let stateName = ""
  if (flag == "1") {
    stateName = "启动"
  } else {
    stateName = '停止'
    stateName = "停止"
  }
  getSettingCount(ids.value).then(response => {
  getSettingCount(ids.value).then((response) => {
    let unStartStopArrName = []
    let startStopArrIds = []
    for (let i = 0; i < response.data.length; i++) {
@@ -146,19 +152,20 @@
      }
    }
    if (unStartStopArrName.length > 0) {
      var bh = unStartStopArrName.join(',')
      proxy.$modal.confirm('选中存在未设置限值的仪器设备' + bh + ',暂无法' + stateName + '!', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(function () {
      var bh = unStartStopArrName.join(",")
      proxy.$modal
        .confirm("选中存在未设置限值的仪器设备" + bh + ",暂无法" + stateName + "!", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
      })
        .catch(function () {})
    } else {
      if (startStopArrIds.length > 0) {
        updateSet(startStopArrIds || '', flag).then(response => {
        updateSet(startStopArrIds || "", flag).then((response) => {
          if (response.code === 200) {
            initStartStop()
            proxy.$modal.msgSuccess('成功')
            proxy.$modal.msgSuccess("成功")
          } else {
            proxy.$modal.msgError(response.msg)
          }
@@ -168,8 +175,8 @@
  })
}
defineExpose({
  getList
});
  getList,
})
</script>
<style lang='scss' scoped></style>
<style lang="scss" scoped></style>
zhitan-vue/src/views/businessconfiguration/prealarmmanage/components/statisticalindicatorsmanage/StatisticalIndicatorsManage.vue
@@ -1,6 +1,6 @@
<template>
  <div class="table-box">
    <div class="form-card">
    <div class="form-card" style="padding: 16px 16px 0 16px">
      <el-form :model="queryParams" ref="queryRef" :inline="true">
        <el-form-item label="采集点名称">
          <el-input v-model="queryParams.name" placeholder="请输入采集点名称" maxlength="30" />
@@ -9,9 +9,7 @@
          <el-input v-model="queryParams.code" placeholder="请输入采集点编码" maxlength="30" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="getTabList">
            æœç´¢
          </el-button>
          <el-button type="primary" icon="Search" @click="getTabList"> æœç´¢ </el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <el-form-item>
@@ -24,29 +22,38 @@
        </el-form-item>
      </el-form>
    </div>
    <el-table v-loading="loading" row-key="indexId" ref="tableRef" :data="tableData"
      @selection-change="handleSelectionChange" height="calc(100vh - 430px)"
      :default-sort="{ prop: 'date', order: 'descending' }">
    <el-table
      v-loading="loading"
      row-key="indexId"
      ref="tableRef"
      :data="tableData"
      @selection-change="handleSelectionChange"
      height="calc(100vh - 430px)"
      :default-sort="{ prop: 'date', order: 'descending' }"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="采集点名称" align="center" prop="name" />
      <el-table-column label="采集点编码" align="center" prop="code" />
      <el-table-column label="启停状态" align="center" prop="indexCategory" />
      <el-table-column label="操作" width="150" align="center">
        <template #default="scope">
          <el-button link type="primary" @click="handleAlarm(scope.row)">
            æŠ¥è­¦
          </el-button>
          <el-button link type="primary" @click="handleAlarm(scope.row)"> æŠ¥è­¦ </el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="queryParams.total > 0" :total="queryParams.total" v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize" @pagination="getTabList" />
    <pagination
      v-show="queryParams.total > 0"
      :total="queryParams.total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getTabList"
    />
    <StatisticsAlarmModal ref="statisticsAlarmModalRef" />
  </div>
</template>
<script setup>
import StatisticsAlarmModal from './StatisticsAlarmModal.vue'
import { getSettingIndex, getStartStop, getSettingCount, updateSet } from '@/api/businessConfiguration/preAlarmManage'
import StatisticsAlarmModal from "./StatisticsAlarmModal.vue"
import { getSettingIndex, getStartStop, getSettingCount, updateSet } from "@/api/businessConfiguration/preAlarmManage"
let { proxy } = getCurrentInstance()
const data = reactive({
@@ -58,8 +65,8 @@
    pageSize: 10,
    total: 0,
  },
});
const { queryParams } = toRefs(data);
})
const { queryParams } = toRefs(data)
let ids = ref([])
let names = ref([])
let single = ref(true)
@@ -73,41 +80,40 @@
function getList(modelNode) {
  currentNode.value = modelNode
  queryParams.value.nodeId = modelNode.id
  queryParams.value.indexType = 'STATISTIC',
    getTabList()
  ;(queryParams.value.indexType = "STATISTIC"), getTabList()
}
function getTabList() {
  loading.value = true;
  getSettingIndex(queryParams.value).then(res => {
    tableData.value = res.data.records;
  loading.value = true
  getSettingIndex(queryParams.value).then((res) => {
    tableData.value = res.data.records
    queryParams.value.total = res.data.total
    loading.value = false;
    loading.value = false
    initStartStop()
  })
}
function resetQuery() {
  proxy.resetForm("queryRef");
  queryParams.value.code = null;
  queryParams.value.name = null;
  queryParams.value.pageNum = 1;
  queryParams.value.pageSize = 10;
  queryParams.value.total = 0;
  getTabList();
  proxy.resetForm("queryRef")
  queryParams.value.code = null
  queryParams.value.name = null
  queryParams.value.pageNum = 1
  queryParams.value.pageSize = 10
  queryParams.value.total = 0
  getTabList()
}
function initStartStop() {
  for (let i = 0; i < tableData.value.length; i++) {
    let ndy = ''
    getStartStop(tableData.value[i].indexId).then(response => {
      if (response.code == '200') {
        if (response.msg == '1') {
          tableData.value[i].indexCategory = '启动'
        } else if (response.msg == '2') {
          tableData.value[i].indexCategory = '停止'
    let ndy = ""
    getStartStop(tableData.value[i].indexId).then((response) => {
      if (response.code == "200") {
        if (response.msg == "1") {
          tableData.value[i].indexCategory = "启动"
        } else if (response.msg == "2") {
          tableData.value[i].indexCategory = "停止"
        } else {
          tableData.value[i].indexCategory = '尚未设置'
          tableData.value[i].indexCategory = "尚未设置"
        }
      } else {
        tableData.value[i].indexCategory = ''
        tableData.value[i].indexCategory = ""
      }
    })
  }
@@ -120,22 +126,22 @@
// å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.indexId)
  names.value = selection.map(item => item.name)
  ids.value = selection.map((item) => item.indexId)
  names.value = selection.map((item) => item.name)
  single.value = selection.length !== 1
  multiple.value = !selection.length
  startStopOptions.value = selection.map(item => item.indexCategory)
  codeOptions.value = selection.map(item => item.code)
  startStopOptions.value = selection.map((item) => item.indexCategory)
  codeOptions.value = selection.map((item) => item.code)
}
function handleUpdateState(flag) {
  let stateName = ''
  if (flag == '1') {
    stateName = '启动'
  let stateName = ""
  if (flag == "1") {
    stateName = "启动"
  } else {
    stateName = '停止'
    stateName = "停止"
  }
  getSettingCount(ids.value).then(response => {
  getSettingCount(ids.value).then((response) => {
    let unStartStopArrName = []
    let startStopArrIds = []
    for (let i = 0; i < response.data.length; i++) {
@@ -146,19 +152,20 @@
      }
    }
    if (unStartStopArrName.length > 0) {
      var bh = unStartStopArrName.join(',')
      proxy.$modal.confirm('选中存在未设置限值的仪器设备' + bh + ',暂无法' + stateName + '!', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(function () {
      var bh = unStartStopArrName.join(",")
      proxy.$modal
        .confirm("选中存在未设置限值的仪器设备" + bh + ",暂无法" + stateName + "!", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
      })
        .catch(function () {})
    } else {
      if (startStopArrIds.length > 0) {
        updateSet(startStopArrIds || '', flag).then(response => {
        updateSet(startStopArrIds || "", flag).then((response) => {
          if (response.code === 200) {
            initStartStop()
            proxy.$modal.msgSuccess('成功')
            proxy.$modal.msgSuccess("成功")
          } else {
            proxy.$modal.msgError(response.msg)
          }
@@ -168,8 +175,8 @@
  })
}
defineExpose({
  getList
});
  getList,
})
</script>
<style lang='scss' scoped></style>
<style lang="scss" scoped></style>
zhitan-vue/src/views/businessconfiguration/prealarmmanage/prealarmmanage.vue
@@ -6,13 +6,9 @@
            </div>
            <div class="page-container-right">
                <div class="page-container-right">
                    <div class="mb20 mt20 ml20 tab-box">
                        <div class="tab-li" :class="tab == 1 ? 'is-tab' : ''" @click="handleTab('1')">
                            é‡‡é›†ç‚¹ç®¡ç†
                        </div>
                        <div class="tab-li" :class="tab == 2 ? 'is-tab' : ''" @click="handleTab('2')">
                            ç»Ÿè®¡æŒ‡æ ‡ç®¡ç†
                        </div>
          <div class="tab-box">
            <div class="tab-li" :class="tab == 1 ? 'is-tab' : ''" @click="handleTab('1')">采集点管理</div>
            <div class="tab-li" :class="tab == 2 ? 'is-tab' : ''" @click="handleTab('2')">统计指标管理</div>
                    </div>
                    <BaseCard :title="currentNode ? currentNode.label + '--节点配置' : '暂无节点配置'">
                        <div>
@@ -26,18 +22,17 @@
                    </BaseCard>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup name="preAlarmManage">
import CollectionPointManage from './components/collectionpointmanage/CollectionPointManage.vue'
import StatisticalIndicatorsManage from './components/statisticalindicatorsmanage/StatisticalIndicatorsManage.vue'
import CollectionPointManage from "./components/collectionpointmanage/CollectionPointManage.vue"
import StatisticalIndicatorsManage from "./components/statisticalindicatorsmanage/StatisticalIndicatorsManage.vue"
let currentNode = ref()
let tab = ref('1')
let tab = ref("1")
let collectionPointManageRef = ref()
let statisticalIndicatorsManageRef = ref('1')
let statisticalIndicatorsManageRef = ref("1")
function handleTab(value) {
    tab.value = value
@@ -48,8 +43,7 @@
        if (value == 2 && statisticalIndicatorsManageRef.value) {
            statisticalIndicatorsManageRef.value.getList(currentNode.value)
        }
    });
  })
}
function handleNodeClick(data) {
@@ -57,11 +51,9 @@
    handleTab(tab.value)
    // handleQuery();
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.page-box {
    height: calc(100vh - 145px);
@@ -95,8 +87,6 @@
            margin-right: 5px;
        }
    }
}
:deep .el-tabs__nav-wrap:after {
@@ -105,7 +95,7 @@
:deep .el-tabs__item {
    color: #fff;
    font-size: 20px;
  //   font-size: 20px;
    padding: 0 20px;
    &.is-active,
@@ -118,23 +108,36 @@
    display: flex;
    align-items: center;
    color: #fff;
    border-bottom: 1px solid #3371EB;
  border-bottom: 1px solid #3371eb;
    margin-right: 20px;
  font-size: 15px;
  margin-left: 15px;
    .tab-li {
        cursor: pointer;
        border: 1px solid #3371EB;
        padding: 10px 25px;
    border: 1px solid #3371eb;
    padding: 8px 20px;
        border-radius: 5px 5px 0 0;
    }
    .is-tab {
        background: #3371EB;
    background: #3371eb;
    color: #fff;
  }
}
.themeDark {
  .tab-box {
    color: #fff;
  }
}
.themeLight {
  .tab-box {
    color: #333;
    }
}
.content-box {
    height: calc(100vh - 317px) !important;
}
</style>
zhitan-vue/src/views/carbonemission/carbonEmission.vue
@@ -8,53 +8,54 @@
        <div class="form-card">
          <el-form :model="queryParams" ref="queryRef" :inline="true">
            <el-form-item label="期间" prop="timeType">
              <el-select v-model="queryParams.timeType" placeholder="期间" clearable style="width: 120px"
                @change="handleTimeType">
              <el-select
                v-model="queryParams.timeType"
                placeholder="期间"
                clearable
                style="width: 120px"
                @change="handleTimeType"
              >
                <el-option v-for="dict in period" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="时间">
              <el-date-picker v-model="queryParams.dataTime" :type="queryParams.timeType == 'YEAR'
                ? 'year'
                : queryParams.timeType == 'MONTH'
                  ? 'month'
                  : 'date'
                " :format="queryParams.timeType == 'YEAR'
                  ? 'YYYY'
                  : queryParams.timeType == 'MONTH'
                    ? 'YYYY-MM'
                    : 'YYYY-MM-DD'
                  " value-format="YYYY-MM-DD" placeholder="时间" style="width: 100%" />
              <el-date-picker
                v-model="queryParams.dataTime"
                :type="queryParams.timeType == 'YEAR' ? 'year' : queryParams.timeType == 'MONTH' ? 'month' : 'date'"
                :format="
                  queryParams.timeType == 'YEAR' ? 'YYYY' : queryParams.timeType == 'MONTH' ? 'YYYY-MM' : 'YYYY-MM-DD'
                "
                value-format="YYYY-MM-DD"
                placeholder="时间"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">
                æœç´¢
              </el-button>
              <el-button type="primary" icon="Search" @click="handleQuery"> æœç´¢ </el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Download" @click="handleExport">
                å¯¼å‡º
              </el-button>
              <el-button type="warning" icon="Download" @click="handleExport"> å¯¼å‡º </el-button>
            </el-form-item>
          </el-form>
        </div>
        <div style="
            height: calc(100vh - 220px) !important;
            max-height: calc(100vh - 220px) !important;
            overflow-y: auto;
          ">
          <div class="card-list" v-if="listTop.length > 1">
        <div
          style="height: calc(100vh - 220px) !important; max-height: calc(100vh - 220px) !important; overflow-y: auto"
        >
          <!-- <div class="" v-if="listTop.length > 1" style="margin: 12px 0 0 18px">
            <el-button @click="dialogVisible = true"> æŸ¥çœ‹æ›´å¤š </el-button>
          </div>
          </div> -->
          <template v-for="(row, rowIndex) in listTop" :key="rowIndex" v-loading="loading">
            <div class="card-list" v-if="rowIndex == 0">
              <template v-for="(item, index) in row" :key="index">
                <div class="card-list-item">
                  <div class="item-top">
                    <div class="top-icon" :style="{
                    <div
                      class="top-icon"
                      :style="{
                      backgroundImage: 'url(' + bgList[index].icon + ')',
                    }" />
                      }"
                    />
                    <div class="top-right">
                      {{ item.allEneryType }}
                    </div>
@@ -69,12 +70,10 @@
                    <div class="bottom-left">同比</div>
                    <div class="bottom-right" :style="{ color: bgList[index].color }">
                      {{ Math.abs(item.yoyEnery) }}%
                      <el-icon v-if="!!item.yoyEnery" :color="item.yoyEnery > 0
                        ? 'green'
                        : item.yoyEnery < 0
                          ? 'red'
                          : ''
                        ">
                      <el-icon
                        v-if="!!item.yoyEnery"
                        :color="item.yoyEnery > 0 ? 'green' : item.yoyEnery < 0 ? 'red' : ''"
                      >
                        <Top v-if="item.yoyEnery > 0" />
                        <Bottom v-if="item.yoyEnery < 0" />
                      </el-icon>
@@ -84,25 +83,23 @@
              </template>
            </div>
          </template>
          <BaseCard :title="queryParams.nodeName +
            '-碳排放量同环比(' +
            queryParams.dataTime +
            ')'
            ">
          <BaseCard :title="queryParams.nodeName + '-碳排放量同环比(' + queryParams.dataTime + ')'">
            <div class="chart-box" v-loading="loading">
              <div id="Chart1" />
            </div>
          </BaseCard>
          <BaseCard :title="queryParams.nodeName +
            '-碳排放量统计分析表(' +
            queryParams.dataTime +
            ')'
            ">
          <BaseCard :title="queryParams.nodeName + '-碳排放量统计分析表(' + queryParams.dataTime + ')'">
            <div class="table-box">
              <el-table :data="listBottom" v-loading="loading">
                <el-table-column label="时间" align="center" key="xaxis" prop="xaxis" :show-overflow-tooltip="true" />
                <el-table-column label="破排放量(tCO₂e)
                  " align="center" key="yaxis" prop="yaxis" :show-overflow-tooltip="true" />
                <el-table-column
                  label="破排放量(tCO₂e)
                  "
                  align="center"
                  key="yaxis"
                  prop="yaxis"
                  :show-overflow-tooltip="true"
                />
                <el-table-column label="同比" align="center" key="yoy" prop="yoy" :show-overflow-tooltip="true" />
                <el-table-column label="环比" align="center" key="qoq" prop="qoq" :show-overflow-tooltip="true" />
              </el-table>
@@ -117,9 +114,12 @@
          <template v-for="(item, index) in row" :key="index">
            <div class="card-list-item">
              <div class="item-top">
                <div class="top-icon" :style="{
                <div
                  class="top-icon"
                  :style="{
                  backgroundImage: 'url(' + bgList[index].icon + ')',
                }" />
                  }"
                />
                <div class="top-right">
                  {{ item.allEneryType }}
                </div>
@@ -134,12 +134,7 @@
                <div class="bottom-left">同比</div>
                <div class="bottom-right" :style="{ color: bgList[index].color }">
                  {{ Math.abs(item.yoyEnery) }}%
                  <el-icon v-if="!!item.yoyEnery" :color="item.yoyEnery > 0
                    ? 'green'
                    : item.yoyEnery < 0
                      ? 'red'
                      : ''
                    ">
                  <el-icon v-if="!!item.yoyEnery" :color="item.yoyEnery > 0 ? 'green' : item.yoyEnery < 0 ? 'red' : ''">
                    <Top v-if="item.yoyEnery > 0" />
                    <Bottom v-if="item.yoyEnery < 0" />
                  </el-icon>
@@ -153,29 +148,26 @@
  </div>
</template>
<script setup name="carbonEmission">
import {
  listUpCarbonemission,
  listMiddleCarbonemission,
} from "@/api/carbonemission/carbonemission";
import * as echarts from "echarts";
const { proxy } = getCurrentInstance();
import { useRoute } from "vue-router";
const { period } = proxy.useDict("period");
import useSettingsStore from "@/store/modules/settings";
const settingsStore = useSettingsStore();
import { listUpCarbonemission, listMiddleCarbonemission } from "@/api/carbonemission/carbonemission"
import * as echarts from "echarts"
const { proxy } = getCurrentInstance()
import { useRoute } from "vue-router"
const { period } = proxy.useDict("period")
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
watch(
  () => settingsStore.sideTheme,
  (val) => {
    getList();
    getList()
  }
);
const loading = ref(false);
const dialogVisible = ref(false);
import icon1 from "@/assets/images/period/icon1.png";
import icon2 from "@/assets/images/period/icon2.png";
import icon3 from "@/assets/images/period/icon3.png";
import icon4 from "@/assets/images/period/icon4.png";
import icon5 from "@/assets/images/period/icon5.png";
)
const loading = ref(false)
const dialogVisible = ref(false)
import icon1 from "@/assets/images/period/icon1.png"
import icon2 from "@/assets/images/period/icon2.png"
import icon3 from "@/assets/images/period/icon3.png"
import icon4 from "@/assets/images/period/icon4.png"
import icon5 from "@/assets/images/period/icon5.png"
const bgList = ref([
  {
    icon: icon1,
@@ -197,9 +189,9 @@
    icon: icon5,
    color: "#78e801",
  },
]);
const listTop = ref([]);
const listBottom = ref([]);
])
const listTop = ref([])
const listBottom = ref([])
const data = reactive({
  queryParams: {
    nodeId: null,
@@ -208,23 +200,23 @@
    dataTime: null,
  },
  query: { ...useRoute().query },
});
const { queryParams, query } = toRefs(data);
})
const { queryParams, query } = toRefs(data)
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id;
  queryParams.value.nodeName = data.label;
  handleTimeType(period.value[0].value);
  handleQuery();
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  handleTimeType(period.value[0].value)
  handleQuery()
}
function handleTimeType(e) {
  queryParams.value.timeType = e;
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD");
  queryParams.value.timeType = e
  queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
}
// ç¢³æŽ’放管理-碳排放量核算-列表
function getList() {
  loading.value = true;
  listTop.value = [];
  loading.value = true
  listTop.value = []
  listUpCarbonemission(
    proxy.addDateRange({
      ...queryParams.value,
@@ -233,15 +225,15 @@
  ).then((res) => {
    res.data.upData.map((item, index) => {
      if (index % 5 === 0) {
        listTop.value.push(res.data.upData.slice(index, index + 5));
        listTop.value.push(res.data.upData.slice(index, index + 5))
      }
    });
  });
    })
  })
  // åœ¨åˆå§‹åŒ–之前,先dispose旧的实例
  if (echarts.getInstanceByDom(document.getElementById("Chart1"))) {
    echarts.dispose(document.getElementById("Chart1"));
    echarts.dispose(document.getElementById("Chart1"))
  }
  const myChart1 = echarts.init(document.getElementById("Chart1"));
  const myChart1 = echarts.init(document.getElementById("Chart1"))
  listMiddleCarbonemission(
    proxy.addDateRange({
      emissionType: "allType",
@@ -250,19 +242,19 @@
    })
  ).then((res) => {
    if (!!res.code && res.code == 200) {
      loading.value = false;
      let xaxis = [];
      let yaxis = [];
      let yoy = [];
      let qoq = [];
      loading.value = false
      let xaxis = []
      let yaxis = []
      let yoy = []
      let qoq = []
      if (!!res.data) {
        res.data.map((item) => {
          xaxis.push(item.xaxis);
          yaxis.push(!!item.yaxis ? item.yaxis : 0);
          yoy.push(!!item.yoy ? item.yoy : 0);
          qoq.push(!!item.qoq ? item.qoq : 0);
        });
        listBottom.value = res.data;
          xaxis.push(item.xaxis)
          yaxis.push(!!item.yaxis ? item.yaxis : 0)
          yoy.push(!!item.yoy ? item.yoy : 0)
          qoq.push(!!item.qoq ? item.qoq : 0)
        })
        listBottom.value = res.data
      }
      setTimeout(() => {
        myChart1.setOption({
@@ -273,10 +265,7 @@
              type: "shadow",
              textStyle: {
                fontSize: 14,
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
              },
            },
          },
@@ -292,8 +281,7 @@
            itemWidth: 14,
            itemHeight: 10,
            textStyle: {
              color:
                settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
              color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
            },
          },
          xAxis: {
@@ -304,10 +292,7 @@
            axisLine: {
              show: true,
              lineStyle: {
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
              },
            },
            axisTick: {
@@ -320,8 +305,7 @@
              show: false,
            },
            axisLabel: {
              color:
                settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
              color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
              fontSize: 14,
              padding: [5, 0, 0, 0],
              //   formatter: '{value} ml'
@@ -333,10 +317,7 @@
              name: "tCO₂e",
              type: "value",
              nameTextStyle: {
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                fontSize: 14,
                padding: [0, 0, 5, 0],
              },
@@ -347,10 +328,7 @@
                show: true,
                lineStyle: {
                  type: "dashed",
                  color:
                    settingsStore.sideTheme == "theme-dark"
                      ? "#FFFFFF"
                      : "#222222",
                  color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                },
              },
              axisTick: {
@@ -360,10 +338,7 @@
                show: false,
              },
              axisLabel: {
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                fontSize: 14,
              },
            },
@@ -372,10 +347,7 @@
              name: "%",
              alignTicks: true,
              nameTextStyle: {
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                fontSize: 14,
                padding: [0, 0, 5, 0],
              },
@@ -389,20 +361,14 @@
                show: true,
                lineStyle: {
                  type: "dashed",
                  color:
                    settingsStore.sideTheme == "theme-dark"
                      ? "#FFFFFF"
                      : "#222222",
                  color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                },
              },
              splitArea: {
                show: false,
              },
              axisLabel: {
                color:
                  settingsStore.sideTheme == "theme-dark"
                    ? "#FFFFFF"
                    : "#222222",
                color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
                fontSize: 14,
              },
            },
@@ -411,7 +377,7 @@
            {
              name: "碳排放量",
              type: "bar",
              barWidth: "27",
              barWidth: "12",
              itemStyle: {
                borderRadius: [15, 15, 0, 0],
              },
@@ -438,29 +404,29 @@
              data: qoq,
            },
          ],
        });
      }, 100);
        })
      }, 100)
      window.addEventListener(
        "resize",
        () => {
          myChart1.resize();
          myChart1.resize()
        },
        { passive: true }
      );
      )
    }
  });
  })
}
// ç¢³æŽ’放管理-碳排放量核算-搜索
function handleQuery() {
  getList();
  getList()
}
// ç¢³æŽ’放管理-碳排放量核算-重置
function resetQuery() {
  proxy.resetForm("queryRef");
  queryParams.value.timeType = null;
  queryParams.value.dataTime = null;
  handleTimeType(period.value[0].value);
  handleQuery();
  proxy.resetForm("queryRef")
  queryParams.value.timeType = null
  queryParams.value.dataTime = null
  handleTimeType(period.value[0].value)
  handleQuery()
}
// ç¢³æŽ’放管理-碳排放量核算-导出
function handleExport() {
@@ -472,7 +438,7 @@
      ...query.value,
    },
    `${queryParams.value.nodeName}-碳排放量核算_${new Date().getTime()}.xlsx`
  );
  )
}
</script>
<style scoped lang="scss">
zhitan-vue/src/views/comprehensive/comps/LineChart.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,177 @@
<template>
  <div class="chart-box">
    <div id="ChartDom" style="width: 100%; height: 100%"></div>
  </div>
</template>
<script setup>
import * as echarts from "echarts"
const { proxy } = getCurrentInstance()
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
const emit = defineEmits()
const props = defineProps({
  chartData: {
    type: Object,
    default: () => {},
  },
})
watch(
  () => props.chartData,
  (val) => {
    console.log("watch", val)
    initChart()
  }
)
watch(
  () => settingsStore.sideTheme,
  (val) => {
    initChart()
  }
)
onMounted(() => {
  initChart()
})
function initChart(value) {
  const chartDom = document.getElementById("ChartDom")
  if (echarts.getInstanceByDom(chartDom)) {
    echarts.dispose(chartDom)
  }
  const myChart = echarts.init(chartDom)
  let option = {
    title: {
      text: props.chartData.title,
      left: "40",
      textStyle: {
        color: "#2979ff",
      },
    },
    color: ["#40c2ff", "#2979ff", "#ff9900", "#fa3534"],
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    legend: {
      icon: "rect",
      itemWidth: 14,
      itemHeight: 10,
      textStyle: {
        color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
      },
    },
    grid: {
      top: "60",
      left: "50",
      right: "40",
      bottom: "20",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      axisPointer: {
        type: "shadow",
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
        },
      },
      axisTick: {
        show: false,
      },
      splitArea: {
        show: false,
      },
      splitLine: {
        show: false,
      },
      axisLabel: {
        color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
        fontSize: 14,
        padding: [5, 0, 0, 0],
        //   formatter: '{value} ml'
      },
      data: props.chartData.xData,
    },
    yAxis: [
      {
        type: "value",
        nameTextStyle: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          fontSize: 14,
          padding: [0, 0, 5, 0],
        },
        axisLine: {
          show: false,
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: "dashed",
            color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          },
        },
        axisTick: {
          show: false,
        },
        splitArea: {
          show: false,
        },
        axisLabel: {
          color: settingsStore.sideTheme == "theme-dark" ? "#FFFFFF" : "#222222",
          fontSize: 14,
        },
      },
    ],
    series: [
      {
        name: props.chartData.title,
        type: "bar",
        barWidth: "16",
        // tooltip: {
        //   valueFormatter: function (value) {
        //     return value + "tce"
        //   },
        // },
        itemStyle: {
          borderRadius: [15, 15, 0, 0],
        },
        data: props.chartData.yData,
        markPoint: {
          data: [
            { type: "max", name: "Max" },
            { type: "min", name: "Min" },
          ],
        },
      },
    ],
  }
  setTimeout(() => {
    myChart.setOption(option)
  }, 200)
  window.addEventListener(
    "resize",
    () => {
      myChart.resize()
    },
    { passive: true }
  )
}
</script>
<style lang="scss" scoped>
.chart-box {
  width: 100%;
  height: 400px;
  border: 1px solid #eaeaea;
  margin-top: 20px;
  padding-top: 20px;
}
</style>
zhitan-vue/src/views/comprehensive/dailyComprehensive/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,221 @@
<template>
  <div class="page">
    <div class="form-card">
      <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
        <el-form-item label="能源类型" prop="energyType">
          <el-select v-model="queryParams.energyType" placeholder="请选择能源类型">
            <el-option
              :label="item.enername"
              :value="item.enersno"
              v-for="item in energyTypeList"
              :key="item.enersno"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="统计时间">
          <el-date-picker
            v-model="queryParams.dataTime"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择日期"
            style="width: 100%"
            :clearable="false"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <!-- <el-form-item>
          <el-button type="warning" icon="Download" @click="handleExport"> å¯¼å‡º </el-button>
        </el-form-item> -->
      </el-form>
    </div>
    <div class="table-bg-style" style="padding-bottom: 12px">
      <div class="table-box">
        <el-table :data="energyList" v-loading="loading" border max-height="380px">
          <el-table-column fixed prop="indexName" label="指标名称" width="210px">
            <template #default="scope">
              <div style="width: 100%; text-align: left">
                <el-button
                  v-if="scope.row.indexId == queryParams.indexId"
                  icon="search"
                  circle
                  @click="selectChange(scope.row)"
                  style="color: #fff; background: #409eff; margin-right: 8px"
                ></el-button>
                <el-button
                  v-else
                  icon="search"
                  circle
                  @click="selectChange(scope.row)"
                  style="margin-right: 8px"
                ></el-button>
                <el-tooltip
                  v-if="scope.row.indexName && scope.row.indexName.length > 9"
                  class="item"
                  effect="dark"
                  :content="scope.row.indexName"
                  placement="top-end"
                >
                  <span>
                    {{ scope.row.indexName.substr(0, 9) + "..." }}
                  </span>
                </el-tooltip>
                <span v-else>{{ scope.row.indexName }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column v-for="index in 24" :key="index" :label="index - 1 + '时'" align="center" min-width="100">
            <template #default="scope">{{ numFilter(scope.row[`value${index - 1}`]) }}</template>
          </el-table-column>
        </el-table>
        <div>
          <line-chart ref="LineChartRef" :chartData="lineChartData" />
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import {
  getDataList,
  getlistChart,
  exportList,
} from "@/api/comprehensiveStatistics/dailyComprehensive/dailyComprehensive"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import LineChart from "../comps/LineChart.vue"
let { proxy } = getCurrentInstance()
const energyTypeList = ref()
function getEnergyTypeList() {
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    // form.value.indexType = alarm_record_category.value[0].value
    // form.value.energyType = energyTypeList.value[0].enersno
    getList()
  })
}
getEnergyTypeList()
function numFilter(value) {
  // æˆªå–当前数据到小数点后的几位
  let realVal = ""
  if (!isNaN(value) && value !== "" && value !== null) {
    realVal = parseFloat(value).toFixed(2)
  } else {
    realVal = "--"
  }
  return realVal
}
let loading = ref(false)
let total = ref(0)
let queryParams = ref({
  indexStorageId: "",
  indexCode: "",
  pageNum: 1,
  pageSize: 10,
  dataTime: "",
})
const energyList = ref([])
const lineChartData = ref({})
function getList() {
  queryParams.value.indexCode = proxy.$route.query.modelCode
  getDataList({
    ...queryParams.value,
    timeType: "HOUR",
  }).then((response) => {
    energyList.value = response.data
    if (response.data && response.data.length !== 0) {
      selectChange(response.data[0])
    } else {
      lineChartData.value = {}
    }
  })
}
const LineChartRef = ref()
function selectChange(row) {
  queryParams.value.indexId = row ? row.indexId : undefined
  queryParams.value.timeType = "HOUR"
  getlistChart(queryParams.value).then((response) => {
    let actualData = []
    let expectedData = []
    let title = ""
    response.data.forEach((item) => {
      expectedData.push(numFilter(item.value))
      actualData.push(item.timeCode.slice(item.timeCode.length - 2, item.timeCode.length) + "时")
      title = item.indexName + "(" + (item.unitId || "") + ")"
    })
    console.log(response)
    console.log(actualData)
    console.log(expectedData)
    lineChartData.value = {
      xData: actualData,
      yData: expectedData,
      title,
    }
    // LineChartRef.value.initChart()
    // this.lineChartData.actualData = actualData;
    // this.lineChartData.expectedData = expectedData;
    // this.lineChartData.title = title;
    // this.$refs.LineChart.initChart(this.lineChartData);
    // this.$refs.BarChart.initChart(this.lineChartData);
  })
}
function getTime() {
  var date = new Date()
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var date = date.getDate()
  month = month < 10 ? "0" + month : month
  date = date < 10 ? "0" + date : date
  queryParams.value.dataTime = year + "-" + month + "-" + date
}
getTime()
// å¯¼å‡ºæŒ‰é’®æ“ä½œ
function handleExport() {
  exportList(queryParams.value).then((response) => {
    console.log(response)
    // download(response.msg);
  })
}
function handleQuery() {
  queryParams.value.pageNum = 1
  getList()
}
function resetQuery() {
  queryParams.value = {
    limitName: "",
    pageNum: 1,
    pageSize: 10,
    dataTime: null,
  }
  getTime()
  getList()
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
.header-box {
  :deep .el-form-item__content {
    color: #fff;
    font-size: 16px;
  }
}
:deep .el-table--fit {
  border-bottom: 1px solid #eaeaea;
}
</style>
zhitan-vue/src/views/comprehensive/monthlyComprehensive/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,217 @@
<template>
  <div class="page">
    <div class="form-card">
      <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
        <el-form-item label="能源类型" prop="energyType">
          <el-select v-model="queryParams.energyType" placeholder="请选择能源类型">
            <el-option
              :label="item.enername"
              :value="item.enersno"
              v-for="item in energyTypeList"
              :key="item.enersno"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="统计时间">
          <el-date-picker
            style="width: 100%"
            v-model="queryParams.dataTime"
            type="month"
            :clearable="false"
            value-format="YYYY-MM"
            placeholder="选择日期"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
        <!-- <el-form-item>
          <el-button type="warning" icon="Download" @click="handleExport"> å¯¼å‡º </el-button>
        </el-form-item> -->
      </el-form>
    </div>
    <div class="table-bg-style" style="padding-bottom: 12px">
      <div class="table-box">
        <el-table :data="energyList" v-loading="loading" border max-height="380px" height="380">
          <el-table-column fixed prop="indexName" label="指标名称" width="210px">
            <template #default="scope">
              <div style="width: 100%; text-align: left">
                <el-button
                  v-if="scope.row.indexId == queryParams.indexId"
                  icon="search"
                  circle
                  @click="selectChange(scope.row)"
                  style="color: #fff; background: #409eff; margin-right: 8px"
                ></el-button>
                <el-button
                  v-else
                  icon="search"
                  circle
                  @click="selectChange(scope.row)"
                  style="margin-right: 8px"
                ></el-button>
                <el-tooltip
                  v-if="scope.row.indexName && scope.row.indexName.length > 9"
                  class="item"
                  effect="dark"
                  :content="scope.row.indexName"
                  placement="top-end"
                >
                  <span>
                    {{ scope.row.indexName.substr(0, 9) + "..." }}
                  </span>
                </el-tooltip>
                <span v-else>{{ scope.row.indexName }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column v-for="index in 31" :key="index" :label="index + '日'" align="center" min-width="100px">
            <template #default="scope">{{ numFilter(scope.row[`value${index}`]) }}</template>
          </el-table-column>
        </el-table>
        <div>
          <line-chart ref="LineChartRef" :chartData="lineChartData" />
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { getDataList, getlistChart } from "@/api/comprehensiveStatistics/monthlyComprehensive/monthlyComprehensive"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import LineChart from "../comps/LineChart.vue"
let { proxy } = getCurrentInstance()
const energyTypeList = ref()
function getEnergyTypeList() {
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    // form.value.indexType = alarm_record_category.value[0].value
    // form.value.energyType = energyTypeList.value[0].enersno
    getList()
  })
}
getEnergyTypeList()
function numFilter(value) {
  // æˆªå–当前数据到小数点后的几位
  let realVal = ""
  if (!isNaN(value) && value !== "" && value !== null) {
    realVal = parseFloat(value).toFixed(2)
  } else {
    realVal = "--"
  }
  return realVal
}
let loading = ref(false)
let total = ref(0)
let queryParams = ref({
  indexStorageId: "",
  indexCode: "",
  pageNum: 1,
  pageSize: 10,
  dataTime: "",
  timeType: "DAY",
})
const energyList = ref([])
const lineChartData = ref({})
function getList() {
  queryParams.value.indexCode = proxy.$route.query.modelCode
  getDataList({
    ...queryParams.value,
  }).then((response) => {
    console.log("1111111111", response)
    energyList.value = response.data.tabledata
    if (energyList.value && energyList.value.length !== 0) {
      selectChange(energyList.value[0])
    } else {
      lineChartData.value = {}
    }
  })
}
const LineChartRef = ref()
function selectChange(row) {
  queryParams.value.indexId = row ? row.indexId : undefined
  getlistChart(queryParams.value).then((response) => {
    let actualData = []
    let expectedData = []
    let title = ""
    response.data.forEach((item) => {
      expectedData.push(numFilter(item.value))
      actualData.push(item.timeCode.slice(item.timeCode.length - 2, item.timeCode.length) + "日")
      title = item.indexName + "(" + (item.unitId || "") + ")"
    })
    console.log(response)
    console.log(actualData)
    console.log(expectedData)
    lineChartData.value = {
      xData: actualData,
      yData: expectedData,
      title,
    }
    // LineChartRef.value.initChart()
    // this.lineChartData.actualData = actualData;
    // this.lineChartData.expectedData = expectedData;
    // this.lineChartData.title = title;
    // this.$refs.LineChart.initChart(this.lineChartData);
    // this.$refs.BarChart.initChart(this.lineChartData);
  })
}
function getTime() {
  var date = new Date()
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var date = date.getDate()
  month = month < 10 ? "0" + month : month
  date = date < 10 ? "0" + date : date
  queryParams.value.dataTime = year + "-" + month
}
getTime()
// å¯¼å‡ºæŒ‰é’®æ“ä½œ
function handleExport() {
  exportList(queryParams.value).then((response) => {
    console.log(response)
    // download(response.msg);
  })
}
function handleQuery() {
  queryParams.value.pageNum = 1
  getList()
}
function resetQuery() {
  queryParams.value = {
    limitName: "",
    pageNum: 1,
    pageSize: 10,
    dataTime: null,
    timeType: "DAY",
  }
  getTime()
  getList()
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
.header-box {
  :deep .el-form-item__content {
    color: #fff;
    font-size: 16px;
  }
}
:deep .el-table--fit {
  border-bottom: 1px solid #eaeaea;
}
</style>
在上述文件截断后对比
zhitan-vue/src/views/comprehensive/yearComprehensive/index.vue zhitan-vue/src/views/costAnalysis/cost-trend-analysis.vue zhitan-vue/src/views/costAnalysis/energy-trend-analysis.vue zhitan-vue/src/views/dataMonitoring/historyDataTrend/index.vue zhitan-vue/src/views/deepanalysis/deepAnalysis.vue zhitan-vue/src/views/energy/energy.vue zhitan-vue/src/views/energyanalysis/comprehensive/comprehensive.vue zhitan-vue/src/views/energyanalysis/department/department.vue zhitan-vue/src/views/energyanalysis/equipment/equipment.vue zhitan-vue/src/views/energyconservation/policyrule/components/EditModal copy.vue (已删除) zhitan-vue/src/views/energyconservation/policyrule/policyRule.vue zhitan-vue/src/views/energyconservation/projectmanage/projectmanage/projectManage.vue zhitan-vue/src/views/energyefficiency/benchmarkmanage/benchmarkmanage.vue zhitan-vue/src/views/index.vue zhitan-vue/src/views/keyEquipment/comps/LineChart.vue zhitan-vue/src/views/keyEquipment/daily/index.vue zhitan-vue/src/views/keyEquipment/monthly/index.vue zhitan-vue/src/views/keyEquipment/year/index.vue zhitan-vue/src/views/login.vue zhitan-vue/src/views/measuringinstruments/distributionroom/distributionroom.vue zhitan-vue/src/views/measuringinstruments/maintain/maintain.vue zhitan-vue/src/views/modelconfiguration/businessmodel/businessModel.vue zhitan-vue/src/views/modelconfiguration/businessmodel/components/collectIndicators/CollectIndicators.vue zhitan-vue/src/views/modelconfiguration/businessmodel/components/deviceConfig/DeviceConfig.vue zhitan-vue/src/views/modelconfiguration/businessmodel/components/statisticalIndicators/StatisticModal.vue zhitan-vue/src/views/modelconfiguration/businessmodel/components/statisticalIndicators/statisticalIndicators.vue zhitan-vue/src/views/modelconfiguration/calculationformula/calculationFormula.vue zhitan-vue/src/views/modelconfiguration/collectindicator/collectIndicator.vue zhitan-vue/src/views/modelconfiguration/energytype/energyType.vue zhitan-vue/src/views/modelconfiguration/energyvarieties/energyVarieties.vue zhitan-vue/src/views/modelconfiguration/indexwarehouse/components/deviceConfig/DeviceConfig.vue zhitan-vue/src/views/modelconfiguration/indexwarehouse/components/statisticalIndicatorManagement/statisticalIndicatorManagement.vue zhitan-vue/src/views/modelconfiguration/indexwarehouse/indexWarehouse.vue zhitan-vue/src/views/modelconfiguration/setpeakvalley/setPeakValley.vue zhitan-vue/src/views/monitor/job/index.vue zhitan-vue/src/views/monitor/logininfor/index.vue zhitan-vue/src/views/monitor/online/index.vue zhitan-vue/src/views/monitor/operlog/index.vue zhitan-vue/src/views/peakvalley/period/period.vue zhitan-vue/src/views/peakvalley/timeSharing/timeSharing.vue zhitan-vue/src/views/policy/knowledgebase/knowledgeBase.vue zhitan-vue/src/views/poweranalysis/pariPassu/index.vue zhitan-vue/src/views/poweranalysis/perPassu/index.vue zhitan-vue/src/views/powerquality/load/index.vue zhitan-vue/src/views/powerquality/power/index.vue zhitan-vue/src/views/powerquality/threephase/index.vue zhitan-vue/src/views/processEnergy/comps/LineChart.vue zhitan-vue/src/views/processEnergy/daily/index.vue zhitan-vue/src/views/processEnergy/monthly/index.vue zhitan-vue/src/views/processEnergy/year/index.vue zhitan-vue/src/views/realtimemonitor/gatewaystatus/index.vue zhitan-vue/src/views/realtimemonitor/realtimemonitor/components/chart-modal.vue zhitan-vue/src/views/realtimemonitor/realtimemonitor/realtimemonitor.vue zhitan-vue/src/views/register.vue zhitan-vue/src/views/svg/components/configure.vue zhitan-vue/src/views/system/config/index.vue zhitan-vue/src/views/system/dept/index.vue zhitan-vue/src/views/system/dict/index.vue zhitan-vue/src/views/system/menu/index.vue zhitan-vue/src/views/system/name/name.vue zhitan-vue/src/views/system/post/index.vue zhitan-vue/src/views/system/role/index.vue zhitan-vue/src/views/system/user/index.vue zhitan-vue/src/views/system/user/profile/index.vue zhitan-vue/src/views/system/user/profile/resetPwd.vue zhitan-vue/src/views/system/user/profile/userAvatar.vue zhitan-vue/src/views/system/user/profile/userInfo.vue zhitan-vue/src/views/tool/gen/index.vue zhitan-vue/vite.config.js