baoshiwei
2025-04-19 5d36e1f987ef21e44ded2e8a1d06c28094ec1e76
Merge remote-tracking branch 'origin/master'

# Conflicts:
# zhitan-admin/src/main/java/com/zhitan/web/controller/model/EnergyIndexController.java
# zhitan-admin/src/main/resources/application-dev.yml
# zhitan-system/src/main/java/com/zhitan/model/mapper/EnergyIndexMapper.java
# zhitan-system/src/main/java/com/zhitan/model/service/IEnergyIndexService.java
# zhitan-system/src/main/java/com/zhitan/model/service/impl/EnergyIndexServiceImpl.java
# zhitan-system/src/main/resources/mapper/model/EnergyIndexMapper.xml
# zhitan-vue/.env.development
已添加71个文件
已重命名4个文件
已删除1个文件
已修改139个文件
97004 ■■■■■ 文件已修改
LICENSE 238 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
readme/img/0-index.png 补丁 | 查看 | 原始文档 | 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 3635 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/postgre20250416.sql 41159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/zhitan-ems_20250325182628.nb3 补丁 | 查看 | 原始文档 | blame | 历史
sql/zhitan_energy_2025-04-18.sql 40877 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/alarm/AlarmAnalysisController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/alarm/HistoryAlarmController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/branchanalysis/BranchEnergyAnalysisController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/energydatastatistics/EnergyDataStatisticsController.java 2 ●●● 补丁 | 查看 | 原始文档 | 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 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/MonthlyKeyEquipmentController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/keyequipment/YearKeyEquipmentController.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/model/EnergyIndexController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | 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-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/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/src/main/java/com/zhitan/framework/web/service/SysLoginService.java 2 ●●● 补丁 | 查看 | 原始文档 | 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/domain/dto/AlarmAnalysisDTO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/mapper/HistoryAlarmMapper.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/services/IAlarmAnalysisService.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/services/IHistoryAlarmService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/AlarmAnalyisisServiceImpl.java 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/HistoryAlarmServiceImpl.java 98 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/basicdata/domain/vo/MeterImplementModel.java 22 ●●●●● 补丁 | 查看 | 原始文档 | 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/mapper/DailyComprehensiveMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/MonthlyComprehensiveMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/mapper/YearComprehensiveMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | 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 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IyearComprehensive.java 5 ●●●●● 补丁 | 查看 | 原始文档 | 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 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/YearComprehensiveServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | 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 19 ●●●●● 补丁 | 查看 | 原始文档 | 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 6 ●●●●● 补丁 | 查看 | 原始文档 | 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/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/EnergyIndexMapper.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/mapper/ModelNodeMapper.java 21 ●●●●● 补丁 | 查看 | 原始文档 | 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/EnergyIndexServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | 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/service/impl/PeakValleyServiceImpl.java 19 ●●●● 补丁 | 查看 | 原始文档 | 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/domain/DataItem.java 7 ●●●●● 补丁 | 查看 | 原始文档 | 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/statisticalAnalysis/domain/vo/FlowChartsVO.java 3 ●●●● 补丁 | 查看 | 原始文档 | 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/alarm/HistoryAlarmMapper.xml 76 ●●●● 补丁 | 查看 | 原始文档 | 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 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/comprehensivestatistics/YearComprehensiveMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | 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 44 ●●●●● 补丁 | 查看 | 原始文档 | 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/EnergyIndexMapper.xml 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/model/ModelNodeMapper.xml 35 ●●●● 补丁 | 查看 | 原始文档 | 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 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/buildingConsumption/api.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/keyEquipment/api.js 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/process/api.js 51 ●●●●● 补丁 | 查看 | 原始文档 | 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/robot.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/index.scss 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/menu-fix.scss 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/page.scss 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/ruoyi.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/styles/sidebar.scss 106 ●●●●● 补丁 | 查看 | 原始文档 | 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 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/BaseCard/index.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Breadcrumb/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/Echarts/LineChart.vue 2 ●●● 补丁 | 查看 | 原始文档 | 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/views/alarmmanage/alarmrecord/alarmRecord.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/alarmmanage/measuremen/measuremen.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | 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/gatewaystatus/gatewayStatus.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/dailyComprehensive/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/monthlyComprehensive/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/comprehensive/yearComprehensive/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/dataMonitoring/historyDataTrend/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/deepanalysis/deepAnalysis.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energy/energy.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/energyanalysis/equipment/equipment.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/index.vue 510 ●●●●● 补丁 | 查看 | 原始文档 | 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/modelconfiguration/indexwarehouse/components/statisticalIndicatorManagement/statisticalIndicatorManagement.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/poweranalysis/pariPassu/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/poweranalysis/perPassu/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | 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/realtimemonitor.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/register.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/name/name.vue 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/system/user/profile/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/vite.config.js 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE
@@ -1,201 +1,101 @@
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
ZT PUBLIC LICENSE授权协议1.0
ZT PUBLIC LICENSE 1.0
   1. Definitions.
许可
      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.
ZT PUBLIC LICENSE ç”±é’岛智碳未来科技有限公司(www.zhitancloud.com)起草,简称ZTPL协议。
任何人均可使用该协议来发布开源软件,并可对下面协议正文中以下划线标注的空白部分做相应修改,
除此之外的任何内容不得做任何修改。青岛智碳未来科技有限公司拥有对该协议条款的最终解释权。
      "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.
1.1 æˆ‘没有对该软件提供任何技术支持的义务,您可联系我购买商业的技术支持。
1.2 æˆ‘对因使用该软件而产生直接或间接的任何问题不负任何责任。
1.3 å¼€æºä¸ç­‰äºŽå…è´¹ï¼Œå¼€æºä¸ç­‰äºŽæ— ç‰ˆæƒï¼Œå¼€æºè½¯ä»¶çš„发展需要您我共同的努力。
   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
2.1 æ‚¨ä¸ªäººæˆ–您就职的公司(组织)可自由使用该软件,我不对您或您就职公司(组织)的性质做任何限制。
2.2 æ‚¨å¯ä»¥åœ¨æ‚¨ä¸ªäººæˆ–您就职公司(组织)任意数量的电脑上运行该软件,我不对电脑的数量做任何限制。
2.3 æ‚¨å¯ä»¥å¯¹è¯¥è½¯ä»¶æºä»£ç è¿›è¡Œä¿®æ”¹ä»¥é€‚应您个人或您所在公司(组织)使用的要求,您做的改动无需对外发布。
2.4 æ‚¨ä¸ªäººæˆ–您就职公司(组织)使用该软件时,必须保留该软件的所有标志,不得以任何方式隐藏或遮掩任一标志。
      (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
3.1 æ‚¨å¯ä»¥ä½¿ç”¨è¯¥è½¯ä»¶ä¸ºæ‚¨çš„用户部署各种形式的应用,我不对应用的性质做任何限制。
3.2 æ‚¨å¯ä»¥ä½¿ç”¨è¯¥è½¯ä»¶ä¸ºæ‚¨çš„用户部署任意数量的应用,我不对应用的数量做任何限制。
3.3 æ‚¨å¯ä»¥å¯¹è¯¥è½¯ä»¶æºä»£ç è¿›è¡Œä¿®æ”¹ä»¥é€‚应您的用户的要求,您做的改动无需对外发布。
3.4 æ‚¨å¯¹è¯¥è½¯ä»¶æºä»£ç æ‰€åšçš„修改可以源代码或二进制的方式提供给您的用户。
3.5 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶ä¸ºæ‚¨çš„任一用户部署的任一应用都必须保留该软件所有的标志。
3.6 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶ä¸ºæ‚¨çš„任一用户部署的任一应用都不得以任何方式隐藏或遮掩该软件任一标志。
      (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.
4.1 æ‚¨å¯ä»¥ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡ï¼Œä¸ºæ‚¨çš„ç”¨æˆ·æä¾›æœåŠ¡ï¼Œæˆ‘ä¸å¯¹è¯¥æœåŠ¡åŠè¯¥æœåŠ¡ç”¨æˆ·çš„æ€§è´¨åšä»»ä½•é™åˆ¶ã€‚
4.2 æ‚¨å¯ä»¥ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡ï¼Œä¸ºæ‚¨çš„ç”¨æˆ·æä¾›æœåŠ¡ï¼Œæˆ‘ä¸å¯¹è¯¥æœåŠ¡çš„ç”¨æˆ·æ•°é‡åšä»»ä½•é™åˆ¶ã€‚
4.3 æ‚¨å¯ä»¥å¯¹è¯¥è½¯ä»¶æºä»£ç è¿›è¡Œä¿®æ”¹ä»¥é€‚应在线服务的要求,您做的改动无需对外发布。
4.4 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡æ—¶ï¼Œå¿…é¡»ä»¥æ˜Žç¡®çš„æ–¹å¼å‘ŠçŸ¥æ‚¨çš„ç”¨æˆ·è¯¥æœåŠ¡æ˜¯åŸºäºŽè¯¥è½¯ä»¶æ­å»ºçš„ã€‚
4.5 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡ä¸ºæ‚¨çš„ä»»ä¸€ç”¨æˆ·éƒ¨ç½²çš„ä»»ä¸€åº”ç”¨å¿…é¡»ä¿ç•™è¯¥è½¯ä»¶æ‰€æœ‰çš„æ ‡å¿—ã€‚
4.6 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡ä¸ºæ‚¨çš„ä»»ä¸€ç”¨æˆ·éƒ¨ç½²çš„ä»»ä¸€åº”ç”¨ä¸å¾—ä»¥ä»»ä½•æ–¹å¼éšè—æˆ–é®æŽ©è¯¥è½¯ä»¶ä»»ä¸€æ ‡å¿—ã€‚
4.7 æ‚¨ä½¿ç”¨è¯¥è½¯ä»¶æ­å»ºåœ¨çº¿æœåŠ¡æ—¶ï¼Œä¸å¾—ä¸ºæ‚¨çš„ç”¨æˆ·æä¾›åŽ»é™¤ã€éšè—æˆ–é®æŽ©è¯¥è½¯ä»¶ä»»ä¸€æ ‡å¿—çš„åŠŸèƒ½ã€‚
   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.
5.1 æˆ‘欢迎并感谢您将该软件发布在您的个人网站、企业官网或者其他的第三方网站。
5.2 æˆ‘欢迎并感谢您将该软件集成在其他系统中一起发布,比如云服务镜像、操作系统发行版等。
5.3 æ‚¨åœ¨å‘布或者集成该软件的时候,不得对该软件源码做任何改动。
5.4 æ‚¨åœ¨å‘布或者集成该软件的时候,须保留该软件的所有标志。
   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.
6.1 æˆ‘欢迎并感谢您为该软件开发衍生作品。
6.2 æ‚¨å¼€å‘的衍生作品中涉及到对该软件源代码改动的地方,须遵循如下条款:
   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.
6.2.1 å¦‚修改了该软件的源代码,须依据本协议发布修改后的源代码。
6.2.2 å¦‚修改了该软件的源代码,须保留代码里面该软件原有的所有标志。
6.2.3 æ‚¨å¯ä»¥åœ¨ä»£ç ä¸­è¿½åŠ æ‚¨è‡ªå·±çš„æ ‡å¿—ã€‚
6.2.4 æ‚¨å¯ä»¥å¯¹æ‚¨å¼€å‘的衍生作品进行收费。
6.2.5 ç¬¬ä¸‰æ–¹çš„用户可在遵循6.2所有条款下可继续在您开发的衍生作品基础上进行修改并发布。
   END OF TERMS AND CONDITIONS
6.3 æ‚¨å¼€å‘的衍生作品中独立于本软件开发的代码,可以源代码或二进制的方式进行发布,可免费或收费发布。
6.4 æ‚¨å¼€å‘的衍生作品不得以任何方式去除、隐藏或遮掩该软件的任一标志。
   APPENDIX: How to apply the Apache License to your work.
七、发布基于该软件API的应用
      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.
7.1 æˆ‘欢迎并感谢您为该软件开发基于API的各种应用,比如客户端软件等。
7.2 æ‚¨åŸºäºŽè¯¥è½¯ä»¶API机制开发的应用,可以源代码或者二进制的方式进行发布,我对此没有任何限制。
7.3 æ‚¨åŸºäºŽè¯¥è½¯ä»¶API机制开发的应用,授权协议可以自行约定,我对此没有任何限制。
7.4 æ‚¨åŸºäºŽè¯¥è½¯ä»¶API机制开发的应用,可以免费或者收费发布,我对此没有任何限制。
   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.
9.1 å¦‚果您违反了该协议的任一条款,该授权协议将自动终止,我保留通过法律手段追究责任的权利。
README.md
@@ -3,9 +3,12 @@
</div>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">智碳能源管理系统</h1>
<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/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>
## ä»‹ç»
@@ -14,17 +17,78 @@
针对客户场景:政府、园区、企业、工矿、公共建筑等。
## ã€æ³¨æ„ã€‘完整能碳管理平台包含三个部分,<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
已同步更新到github仓库:https://github.com/Andy-Yin/zhitan-ems
## æ–‡æ¡£--均在wiki目录
### github wiki地址:https://github.com/zhitan-cloud/zhitan-ems/wiki
### gitee wiki地址:https://gitee.com/liulingling1993/zhitan-ems/wikis/
## åœ¨çº¿ä½“验
- guestUser/guest@123456
#### guestUser/guest@123456
#### æ¼”示地址:https://demo-ems.zhitancloud.com/
演示地址:https://demo-ems.zhitancloud.com/
## å¼€æºåè®®
zhitan-ems是基于 [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html) å’Œ [ZTPL](./LICENSE) åŒåè®®çš„开源软件。
## ç¤¾åŒºç‰ˆ-功能列表
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. å……电运营平台
## æ¡†æž¶ï¼š
@@ -36,7 +100,9 @@
VUE版本:VUE 3
## ç‰¹è‰²ï¼šæ•°æ®é©±åŠ¨çš„è®¡ç®—æ¨¡åž‹å’Œä¸šåŠ¡æ¨¡åž‹é…ç½®
1.  æ”¯æŒåŠ¨æ€ç‚¹ä½é…ç½®ã€‚
1. ç²¾å¿ƒè®¾è®¡çš„展示界面。
 ![输入图片说明](readme/img/0-index.png)
2. æ”¯æŒåŠ¨æ€ç‚¹ä½é…ç½®ã€‚
![输入图片说明](readme/img/指标配置.png)
2.  æ”¯æŒè®¡ç®—公式。
![输入图片说明](readme/img/计算公式.png)
@@ -48,46 +114,6 @@
## äº®ç‚¹åŠŸèƒ½
![输入图片说明](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.  æ°´åŒçŽ¯æ¯”åˆ†æž
   8.3.  å…¶ä»–能源品种分析
9. æ™ºèƒ½æŠ¥è­¦
   9.1.  æŠ¥è­¦åˆ†æž
   9.2.  æŠ¥è­¦é…ç½®
10. å•耗分析
11. è®¡åˆ’与实绩
12. ç”¨èƒ½è€ƒæ ¸
13. ç”¨èƒ½å¯¹æ ‡
14. æ•°æ®è¡¥å½•
15. èŠ‚èƒ½é¡¹ç›®ç®¡ç†
16. èƒ½æºå¹³è¡¡åˆ†æž
17. èƒ½æºå¯¹æ ‡åˆ†æž
18. æ¨¡åž‹é…ç½®ç®¡ç†ï¼ˆè®¡ç®—模型等)
19. åŸºç¡€æ•°æ®ç®¡ç†ï¼ˆå­—典、能源类型等)
20. ç³»ç»Ÿç®¡ç†ï¼ˆç”¨æˆ·ã€è§’色、权限等)
## UI展示(平台分深色和浅色两种风格切换)
@@ -127,12 +153,16 @@
## æ²Ÿé€šäº¤æµ
扫码添加微信交流,加微信请备注:ems。
应很多开发者私信,我创建了QQ群交流,群号:,请备注:ems+姓名。
<p align="center">
  <img src="readme/img/image.png" width=50% height=50%>
  <img src="readme/img/qq.png" width=50% height=50%>
</p>
扫码添加微信交流,加微信请备注:ems+姓名。
<p align="center">
  <img src="readme/img/image-yc.png" width=50% height=50%>
</p>
## å‚与贡献
readme/img/0-index.png
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/postgre20250416.sql
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
sql/zhitan-ems_20250325182628.nb3
Binary files differ
sql/zhitan_energy_2025-04-18.sql
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
zhitan-admin/src/main/java/com/zhitan/web/controller/alarm/AlarmAnalysisController.java
ÎļþÃû´Ó zhitan-admin/src/main/java/com/zhitan/web/controller/alarm/AlarmAnalyisisController.java ÐÞ¸Ä
@@ -2,36 +2,41 @@
import com.zhitan.alarm.domain.dto.AlarmAnalysisDTO;
import com.zhitan.alarm.domain.vo.AlarmAnalysisVO;
import com.zhitan.alarm.services.IAlarmAnalyisisService;
import com.zhitan.alarm.services.IAlarmAnalysisService;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
geng * description æŠ¥è­¦åˆ†æžç›¸å…³åŠŸèƒ½
* description æŠ¥è­¦åˆ†æžç›¸å…³åŠŸèƒ½
 *
 * @author hmj
 * @date 2024-10-26 17:31
 * @author zhitan
 * @date
 */
@RestController
@RequestMapping("/alarmAnalysis")
public class AlarmAnalyisisController extends BaseController {
public class AlarmAnalysisController extends BaseController {
    @Autowired
    private IAlarmAnalyisisService alarmAnalyisisService;
    private IAlarmAnalysisService alarmAnalysisService;
    @GetMapping("/getByNodeId")
    public AjaxResult getByNodeId(@Validated AlarmAnalysisDTO alarmAnalysisDTO){
        AlarmAnalysisVO alarmAnalysisVO  = alarmAnalyisisService.getByNodeId(alarmAnalysisDTO);
        AlarmAnalysisVO alarmAnalysisVO  = alarmAnalysisService.getByNodeId(alarmAnalysisDTO);
        return AjaxResult.success(alarmAnalysisVO);
    }
    @GetMapping("/getCountInfo")
    public AjaxResult getCountInfo(@Validated AlarmAnalysisDTO alarmAnalysisDTO){
        AlarmAnalysisVO alarmAnalysisVO  = alarmAnalyisisService.getCountInfo(alarmAnalysisDTO);
        if(ObjectUtils.isEmpty(alarmAnalysisDTO.getModelCode())){
            return AjaxResult.error("模型编码不能为空");
        }
        AlarmAnalysisVO alarmAnalysisVO  = alarmAnalysisService.getCountInfo(alarmAnalysisDTO);
        return AjaxResult.success(alarmAnalysisVO);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/alarm/HistoryAlarmController.java
@@ -12,6 +12,7 @@
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.framework.web.service.TokenService;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
import io.swagger.annotations.Api;
@@ -43,10 +44,7 @@
public class HistoryAlarmController extends BaseController
{
    @Autowired
    private IHistoryAlarmService iHistoryAlarmService;
    @Autowired
    private TokenService tokenService;
    private IHistoryAlarmService historyAlarmService;
    @Autowired
    private RealtimeDatabaseService realtimeDatabaseService;
@@ -55,12 +53,11 @@
     * åŽ†å²æŠ¥è­¦ é¡µé¢ æ ¹æ® èŠ‚ç‚¹ç›®å½•å’Œ æ¡ä»¶æŸ¥è¯¢
     */
    @ApiOperation("历史报警查询")
//    @PreAuthorize("@ss.hasPermi('energyAlarm:historicalAlarm:list')")
    @PreAuthorize("@ss.hasPermi('energyAlarm:historicalAlarm:list')")
    @GetMapping("/list")
    public TableDataInfo list(JkHistoryAlarm jkHistoryAlarm,Long pageNum,Long pageSize)
    public TableDataInfo list(JkHistoryAlarm jkHistoryAlarm)
    {
        Page<JkHistoryAlarm> list = iHistoryAlarmService.selectJkHistoryAlarmPage(jkHistoryAlarm,pageNum,pageSize);
        return getDataTable(list);
        return getDataTable(historyAlarmService.selectHistoryAlarmPageList(jkHistoryAlarm));
    }
    /**
     * å¯¼å‡ºåŽ†å²æŠ¥è­¦ç›‘æŽ§åˆ—è¡¨
@@ -70,7 +67,7 @@
    @GetMapping("/export")
    public AjaxResult export(JkHistoryAlarm jkHistoryAlarm)
    {
        List<JkHistoryAlarm> list = iHistoryAlarmService.selectJkHistoryAlarmListExcel(jkHistoryAlarm);
        List<JkHistoryAlarm> list = historyAlarmService.selectJkHistoryAlarmListExcel(jkHistoryAlarm);
        ExcelUtil<JkHistoryAlarm> util = new ExcelUtil<JkHistoryAlarm>(JkHistoryAlarm.class);
        return util.exportExcel(list, "alarm");
    }
@@ -165,7 +162,7 @@
    public TableDataInfo listNote(JkHistoryAlarm jkHistoryAlarm)
    {
        startPage();
        List<JkHistoryAlarm> list = iHistoryAlarmService.selectHistoryAlarmNoteList(jkHistoryAlarm);
        List<JkHistoryAlarm> list = historyAlarmService.selectHistoryAlarmNoteList(jkHistoryAlarm);
        return getDataTable(list);
    }
}
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/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/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.getEnergyType());
        return getDataTable(list);
        return success(list);
    }
    @GetMapping("/listChart")
@@ -93,7 +93,7 @@
    }
    /*所有设备*/
    @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.getEnergyType());
            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());
            return AjaxResult.success(reportList);
        } catch (Exception ex) {
            logger.error("获取出错!", ex);
            return AjaxResult.error("获取出错!");
        }
        return success(list);
    }
    @GetMapping("/listChart")
@@ -110,6 +99,7 @@
        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,15 +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;
@@ -18,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;
/**
 *重点设备能耗统计 å¹´
 *
@@ -43,48 +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<>();
        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";
            }
            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.getEnergyType());
        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){
    public AjaxResult listChart(DataItemQueryDTO queryDto){
        List<YearKeyEquipment> list = yearKeyEquipmentService.getListChart(dataItem.getIndexId(),dataItem.getBeginTime(),dataItem.getEndTime(), dataItem.getTimeType(),dataItem.getEnergyType());
        List<YearKeyEquipment> list = yearKeyEquipmentService.getListChart(queryDto);
        return AjaxResult.success(list);
    }
}
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,47 +126,52 @@
  }
  /**
   * åˆ é™¤æŒ‡æ ‡ä¿¡æ¯
     * åˆ é™¤é‡‡é›†æŒ‡æ ‡ä¿¡æ¯
   */
  @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());
    /**
     * å¤„理能源指标列表并生成需要移除的指标ID集合
     * 1. è¿‡æ»¤å‡ºmeterId非空的能源指标对象
     * 2. æå–这些对象的indexId字段
     * 3. å°†æå–的指标ID收集到字符串集合中
     */
    List<String> removeLink = energyIndexList.stream()
        .filter(f -> StringUtils.isNotBlank(f.getMeterId()))
        .map(EnergyIndex::getIndexId)
        .collect(Collectors.toList());
    @DeleteMapping("/{indexIds}")
    public AjaxResult remove(@PathVariable String[] indexIds) {
    if (!removeLink.isEmpty()) {
      energyIndexService.removeNodeIndex(nodeId, removeLink);
        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();
  }
  /**
   * æ–°å¢žé€šè¿‡id删除采集点接口
     * åˆ é™¤ç»Ÿè®¡æŒ‡æ ‡ä¿¡æ¯
   */
  @PreAuthorize("@ss.hasPermi('energyindex:energyindex:remove')")
  @Log(title = "指标信息", businessType = BusinessType.DELETE)
  @DeleteMapping("/{indexId}")
  public AjaxResult deleteCollectIndex(@PathVariable String indexId) {
    return toAjax(energyIndexService.deleteByIndexId(indexId));
    @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();
  }
  @Log(title = "增加计量器具采集点", businessType = BusinessType.INSERT)
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-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/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/src/main/java/com/zhitan/framework/web/service/SysLoginService.java
@@ -76,7 +76,7 @@
    public String login(String username, String password, String code, String uuid)
    {
        // éªŒè¯ç æ ¡éªŒ
        validateCaptcha(username, code, uuid);
//        validateCaptcha(username, code, uuid);
        // ç™»å½•前置校验
        loginPreCheck(username, password);
        // ç”¨æˆ·éªŒè¯
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/domain/dto/AlarmAnalysisDTO.java
@@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zhitan.common.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@@ -13,8 +14,7 @@
 * @author hmj
 * @date 2024-10-16 17:55
 */
@Getter
@Setter
@Data
public class AlarmAnalysisDTO {
    @ApiModelProperty(value = "节点id")
    private String nodeId;
@@ -28,18 +28,23 @@
    /**
     * ç»Ÿè®¡å¼€å§‹æ—¶é—´
     */
    @ApiModelProperty(value = "统计开始时间")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @Excel(name = "报警开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date beginTime;
    /**
     * ç»Ÿè®¡å¼€å§‹æ—¶é—´
     * ç»Ÿè®¡ç»“束时间
     */
    @ApiModelProperty(value = "统计结束时间")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @Excel(name = "报警开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "报警结束时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    /** æ¨¡åž‹ç¼–码 */
    /**
     * æ¨¡åž‹ç¼–码
     */
    @ApiModelProperty(value = "模型编码")
    @Excel(name = "模型编码")
    private String modelCode;
}
zhitan-system/src/main/java/com/zhitan/alarm/mapper/HistoryAlarmMapper.java
@@ -7,6 +7,7 @@
import com.zhitan.alarm.domain.JkHistoryAlarm;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
@@ -35,10 +36,16 @@
   */
  List<JkHistoryAlarm> selectHistoryAlarmNoteList(JkHistoryAlarm jkHistoryAlarm);
  void updateHistoryAlarm(@Param("alarmCode") String alarmCode,
      @Param("historyAlarm") HistoryAlarm historyAlarm);
    void updateHistoryAlarm(@Param("alarmCode") String alarmCode, @Param("historyAlarm") HistoryAlarm historyAlarm);
  Page<JkHistoryAlarm> selectJkHistoryAlarmPage(@Param("jkHistoryAlarm") JkHistoryAlarm jkHistoryAlarm,@Param("page")Page<?> page);
  Integer selectCountByTime(@Param("beginTime") DateTime beginTime, @Param("endTime") DateTime endTime);
    Integer selectCountByTime(@Param("beginTime") DateTime beginTime,
                              @Param("endTime") DateTime endTime,
                              @Param("indexIdList") List<String> indexIdList);
    Page<JkHistoryAlarm> getHistoryAlarmList(@Param("beginTime") Date beginTime,
                                             @Param("endTime") Date endTime,
                                             @Param("indexIdList") List<String> indexIdList,
                                             Page<JkHistoryAlarm> pageInfo);
}
zhitan-system/src/main/java/com/zhitan/alarm/services/IAlarmAnalysisService.java
ÎļþÃû´Ó zhitan-system/src/main/java/com/zhitan/alarm/services/IAlarmAnalyisisService.java ÐÞ¸Ä
@@ -4,13 +4,20 @@
import com.zhitan.alarm.domain.vo.AlarmAnalysisVO;
/**
 * description todu
 * æŠ¥è­¦åˆ†æžæŽ¥å£
 *
 * @author hmj
 * @date 2024-10-26 17:33
 * @author zhitan
 * @date
 */
public interface IAlarmAnalyisisService {
public interface IAlarmAnalysisService {
    AlarmAnalysisVO getByNodeId(AlarmAnalysisDTO alarmAnalysisDTO);
    /**
     * æŠ¥è­¦åˆ†æžç»Ÿè®¡
     *
     * @param alarmAnalysisDTO
     * @return
     */
    AlarmAnalysisVO getCountInfo(AlarmAnalysisDTO alarmAnalysisDTO);
}
zhitan-system/src/main/java/com/zhitan/alarm/services/IHistoryAlarmService.java
@@ -32,5 +32,10 @@
  void updateHistoryAlarm(String alarmCode, HistoryAlarm historyAlarm);
  Page<JkHistoryAlarm> selectJkHistoryAlarmPage(JkHistoryAlarm jkHistoryAlarm, Long pageNum, Long pageSize);
  /**
   * åŽ†å²æŠ¥è­¦åˆ†é¡µæŸ¥è¯¢
   * @param jkHistoryAlarm
   * @return
   */
  Page<JkHistoryAlarm> selectHistoryAlarmPageList(JkHistoryAlarm jkHistoryAlarm);
}
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/AlarmAnalyisisServiceImpl.java
@@ -2,13 +2,14 @@
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.zhitan.alarm.domain.JkHistoryAlarm;
import com.zhitan.alarm.domain.dto.AlarmAnalysisDTO;
import com.zhitan.alarm.domain.vo.AlarmAnalysisVO;
import com.zhitan.alarm.mapper.HistoryAlarmMapper;
import com.zhitan.alarm.services.IAlarmAnalyisisService;
import com.zhitan.basicdata.domain.MeterImplement;
import com.zhitan.alarm.services.IAlarmAnalysisService;
import com.zhitan.basicdata.domain.SysEnergy;
import com.zhitan.basicdata.domain.vo.MeterImplementModel;
import com.zhitan.basicdata.mapper.MeterImplementMapper;
import com.zhitan.basicdata.mapper.SysEnergyMapper;
import com.zhitan.common.enums.IndexType;
@@ -16,8 +17,8 @@
import com.zhitan.common.utils.StringUtils;
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.ModelNode;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.EnergyIndexMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import lombok.AllArgsConstructor;
@@ -25,21 +26,18 @@
import org.springframework.stereotype.Service;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
 * description todu
 * æŠ¥è­¦åˆ†æžå®žçް
 *
 * @author hmj
 * @date 2024-10-26 17:34
 * @author
 * @date
 */
@Service
@AllArgsConstructor
public class AlarmAnalyisisServiceImpl implements IAlarmAnalyisisService {
public class AlarmAnalyisisServiceImpl implements IAlarmAnalysisService {
    private final ModelNodeMapper modelNodeMapper;
    
@@ -50,22 +48,22 @@
    private final EnergyIndexMapper energyIndexMapper;
    
    private final SysEnergyMapper sysEnergyMapper;
    /**
     * æ ¹æ®èŠ‚ç‚¹id获取报警分析信息
     *
     * @param alarmAnalysisDTO
     * @return
     */
    @Override
    public AlarmAnalysisVO getByNodeId(AlarmAnalysisDTO alarmAnalysisDTO) {
        AlarmAnalysisVO alarmAnalysisVO = new AlarmAnalysisVO();
        List<EnergyProportion> alarmProportionList = new ArrayList<>();
        for(IndexType indexType : IndexType.values()){
            EnergyProportion proportion = new EnergyProportion();
            proportion.setEnergyName(indexType.name());
            proportion.setCount(0D);
            proportion.setPercentage(0D);
            alarmProportionList.add(proportion);
        }
        // åˆå§‹åŒ–报警比例列表
        List<EnergyProportion> alarmProportionList = initializeProportionList(IndexType.values());
        // åˆå§‹åŒ–能源比例列表
        List<EnergyProportion> energyProportionList = new ArrayList<>();
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectSysEnergyList(new SysEnergy());
        sysEnergies.forEach(sysEnergy -> {
        sysEnergyMapper.selectSysEnergyList(new SysEnergy()).forEach(sysEnergy -> {
            EnergyProportion proportion = new EnergyProportion();
            proportion.setEnergyName(sysEnergy.getEnersno());
            proportion.setCount(0D);
@@ -103,53 +101,86 @@
        query.setNodeId(nodeId);
        final List<JkHistoryAlarm> jkHistoryAlarms = historyAlarmMapper.selectJkHistoryAlarmList(query);
        if(CollectionUtils.isNotEmpty(jkHistoryAlarms)) {
            // è®¾ç½®èƒ½æºç±»åž‹
            processEnergyType(jkHistoryAlarms);
            // è®¡ç®—报警类型比例
            calculateProportions(jkHistoryAlarms, alarmProportionList, JkHistoryAlarm::getIndexType);
            // è®¡ç®—能源类型比例
            calculateProportions(jkHistoryAlarms, energyProportionList, JkHistoryAlarm::getEnergyId);
            // å¤„理报警时间
            processAlarmTimes(jkHistoryAlarms, timeFormat);
            // ç”Ÿæˆå›¾è¡¨æ•°æ®
            generateChartData(chartDataList, jkHistoryAlarms, beginTime, endTime, timeFormat, queryTimeType);
        }
        alarmAnalysisVO.setAlarmProportion(alarmProportionList);
        alarmAnalysisVO.setEnergyProportion(energyProportionList);
        alarmAnalysisVO.setChartDataList(chartDataList);
        return alarmAnalysisVO;
    }
    /**
     * è®¾ç½®èƒ½æºç±»åž‹
     */
    private void processEnergyType(List<JkHistoryAlarm> jkHistoryAlarms) {
        List<String> indexIds = jkHistoryAlarms.stream().map(JkHistoryAlarm::getIndexId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(indexIds)) {
            List<MeterImplementModel> modelList = energyIndexMapper.selectEnergyTypeByIndex(indexIds);
            if (CollectionUtils.isNotEmpty(modelList)){
                Map<String, String> energyMap = modelList.stream().collect(Collectors.toMap(MeterImplementModel::getIndexId, MeterImplementModel::getEnergyType));
            jkHistoryAlarms.forEach(alarm -> {
                final String indexType = alarm.getIndexType();
                final String indexId = alarm.getIndexId();
                final String alarmNodeId = alarm.getNodeId();
                if ("COLLECT".equals(indexType) && StringUtils.isEmpty(alarm.getEnergyId())) {
                    //根据nodeId和indexId åŽ»æŸ¥è¯¢è®¡é‡å™¨å…·
                    EnergyIndex energyIndex = energyIndexMapper.selectEnergyIndexById(indexId);
                    final MeterImplement meterImplement = meterImplementMapper.selectMeterImplementById(energyIndex.getMeterId());
                    alarm.setEnergyId(meterImplement.getEnergyType());
                    if (IndexType.COLLECT.getDescription().equals(alarm.getIndexType()) && StringUtils.isEmpty(alarm.getEnergyId())){
                        alarm.setEnergyId(energyMap.get(alarm.getIndexId()));
                }
            });
            final Map<String, List<JkHistoryAlarm>> alarmTypeMap = jkHistoryAlarms.stream().collect(Collectors.groupingBy(JkHistoryAlarm::getIndexType));
            alarmTypeMap.forEach((key, value) -> {
                alarmProportionList.forEach(alarm->{
            }
        }
    }
    /**
     * è®¡ç®—占比
     */
    private void calculateProportions(List<JkHistoryAlarm> jkHistoryAlarms, List<EnergyProportion> proportionList, java.util.function.Function<JkHistoryAlarm, String> keyExtractor) {
        Map<String, List<JkHistoryAlarm>> typeMap = jkHistoryAlarms.stream()
                .collect(Collectors.groupingBy(keyExtractor));
        typeMap.forEach((key, value) -> {
            proportionList.forEach(alarm -> {
                    if(alarm.getEnergyName().equals(key)){
                        alarm.setEnergyName(key);
                        alarm.setCount(format2Double(value.size()));
                        double percentage = value.size() / jkHistoryAlarms.size() * 100;
                    double percentage = (double) value.size() / jkHistoryAlarms.size() * 100;
                        alarm.setPercentage(format2Double(percentage));
                    }
                });
            });
            final Map<String, List<JkHistoryAlarm>> energyTypeMap = jkHistoryAlarms.stream().collect(Collectors.groupingBy(JkHistoryAlarm::getEnergyId));
            energyTypeMap.forEach((key, value) -> {
                energyProportionList.forEach(en->{
                    if(en.getEnergyName().equals(key)){
                        en.setEnergyName(key);
                        en.setCount(format2Double(value.size()));
                        double percentage = value.size() / jkHistoryAlarms.size() * 100;
                        en.setPercentage(format2Double(percentage));
                    }
                });
                
            });
    /**
     * å¤„理报警时间
     */
    private void processAlarmTimes(List<JkHistoryAlarm> jkHistoryAlarms, String timeFormat) {
            jkHistoryAlarms.forEach(jkHistoryAlarm -> {
                final String alarmBeginTime = DateUtil.format(jkHistoryAlarm.getAlarmBeginTime(), timeFormat);
            String alarmBeginTime = DateUtil.format(jkHistoryAlarm.getAlarmBeginTime(), timeFormat);
                jkHistoryAlarm.setAlarmTime(alarmBeginTime);
            });
            final Map<String, List<JkHistoryAlarm>> timeMap = jkHistoryAlarms.stream().collect(Collectors.groupingBy(JkHistoryAlarm::getAlarmTime));
    }
    /**
     * ç”Ÿæˆå›¾è¡¨æ•°æ®
     */
    private void generateChartData(List<ChartData> chartDataList, List<JkHistoryAlarm> jkHistoryAlarms, Date beginTime, Date endTime, String timeFormat, String queryTimeType) {
        Map<String, List<JkHistoryAlarm>> timeMap = jkHistoryAlarms.stream()
                .collect(Collectors.groupingBy(JkHistoryAlarm::getAlarmTime));
            while (!beginTime.after(endTime)) {
                final String currentTime = DateUtil.format(beginTime, timeFormat);
                final List<JkHistoryAlarm> value = timeMap.get(currentTime);
            String currentTime = DateUtil.format(beginTime, timeFormat);
            List<JkHistoryAlarm> value = timeMap.get(currentTime);
                ChartData chartData = new ChartData();
                chartData.setXData(currentTime);
                chartData.setYValue(null == value?0:(double)value.size());
            chartData.setYValue(value == null ? 0 : (double) value.size());
                chartDataList.add(chartData);
                switch (TimeType.valueOf(queryTimeType)) {
@@ -165,35 +196,20 @@
                }
            }
        }
        alarmAnalysisVO.setAlarmProportion(alarmProportionList);
        alarmAnalysisVO.setEnergyProportion(energyProportionList);
        alarmAnalysisVO.setChartDataList(chartDataList);
        return alarmAnalysisVO;
    }
    @Override
    public AlarmAnalysisVO getCountInfo(AlarmAnalysisDTO alarmAnalysisDTO) {
        AlarmAnalysisVO alarmAnalysisVO = new AlarmAnalysisVO();
        final String nodeId = alarmAnalysisDTO.getNodeId();
        final DateTime beginOfMonth = DateUtil.beginOfMonth(new Date());
        final DateTime endOfMonth = DateUtil.endOfMonth(new Date());
        final DateTime beginOfYear = DateUtil.beginOfYear(new Date());
        final DateTime endOfYear = DateUtil.endOfYear(new Date());
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
     * åˆå§‹åŒ–占比列表
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,null);
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        Integer monthCount = historyAlarmMapper.selectCountByTime(beginOfMonth,endOfMonth);
        Integer yearCount = historyAlarmMapper.selectCountByTime(beginOfYear,endOfYear);
        alarmAnalysisVO.setIndexCount(indexIds.size());
        alarmAnalysisVO.setMonthCount(monthCount);
        alarmAnalysisVO.setYearCount(yearCount);
        return alarmAnalysisVO;
    private List<EnergyProportion> initializeProportionList(Object[] items) {
        List<EnergyProportion> proportionList = new ArrayList<>();
        for (Object item : items) {
            EnergyProportion proportion = new EnergyProportion();
            proportion.setEnergyName(item.toString());
            proportion.setCount(0D);
            proportion.setPercentage(0D);
            proportionList.add(proportion);
        }
        return proportionList;
    }
    private double format2Double(double averageEnergy) {
@@ -204,4 +220,41 @@
        String formattedResult = df.format(averageEnergy);
        return Double.valueOf(formattedResult);
    }
    /**
     * èŽ·å–æŠ¥è­¦åˆ†æžç»Ÿè®¡ä¿¡æ¯
     * @param alarmAnalysisDTO
     * @return
     */
    @Override
    public AlarmAnalysisVO getCountInfo(AlarmAnalysisDTO alarmAnalysisDTO) {
        AlarmAnalysisVO alarmAnalysisVO = new AlarmAnalysisVO();
        ModelNode parentNode = modelNodeMapper.selectModelNodeById(alarmAnalysisDTO.getNodeId());
        if(ObjectUtils.isEmpty(parentNode)){
            return alarmAnalysisVO;
        }
        // æŸ¥è¯¢æ¨¡åž‹ä¸‹çš„点位数据
        List<ModelNodeIndexInfo> nodeIndexInfoList = modelNodeMapper.getAllModelNodeIndexByAddress(parentNode.getModelCode(), parentNode.getAddress());
        alarmAnalysisVO.setIndexCount(nodeIndexInfoList.size());
        if (CollectionUtils.isEmpty(nodeIndexInfoList)) {
            return alarmAnalysisVO;
        }
        // èŽ·å–æœˆæŠ¥è­¦æ•°ã€å¹´æŠ¥è­¦æ•°
        List<String> indexIdList = nodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        DateTime beginOfMonth = DateUtil.beginOfMonth(new Date());
        DateTime endOfMonth = DateUtil.endOfMonth(new Date());
        DateTime beginOfYear = DateUtil.beginOfYear(new Date());
        DateTime endOfYear = DateUtil.endOfYear(new Date());
        Integer monthCount = historyAlarmMapper.selectCountByTime(beginOfMonth,endOfMonth, indexIdList);
        Integer yearCount = historyAlarmMapper.selectCountByTime(beginOfYear,endOfYear, indexIdList);
        alarmAnalysisVO.setMonthCount(monthCount);
        alarmAnalysisVO.setYearCount(yearCount);
        return alarmAnalysisVO;
    }
}
zhitan-system/src/main/java/com/zhitan/alarm/services/impl/HistoryAlarmServiceImpl.java
@@ -1,5 +1,9 @@
package com.zhitan.alarm.services.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhitan.alarm.domain.HistoryAlarm;
import com.zhitan.alarm.domain.JkHistoryAlarm;
@@ -8,25 +12,42 @@
import com.zhitan.basicdata.domain.MeterImplement;
import com.zhitan.basicdata.mapper.MeterImplementMapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.DateUtils;
import com.zhitan.common.utils.PageUtils;
import com.zhitan.common.utils.StringUtils;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.domain.ModelNode;
import com.zhitan.model.domain.NodeIndex;
import com.zhitan.model.domain.vo.ModelNodeIndexInfo;
import com.zhitan.model.mapper.EnergyIndexMapper;
import com.zhitan.model.mapper.ModelNodeMapper;
import com.zhitan.model.mapper.NodeIndexMapper;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@AllArgsConstructor
@Service
public class HistoryAlarmServiceImpl implements IHistoryAlarmService {
  @Autowired
    @Resource
  private HistoryAlarmMapper historyAlarmMapper;
  @Autowired
    @Resource
  private MeterImplementMapper meterImplementMapper;
  @Autowired
    @Resource
    private ModelNodeMapper modelNodeMapper;
    @Resource
    private NodeIndexMapper nodeIndexMapper;
    @Resource
  private EnergyIndexMapper energyIndexMapper;
@@ -71,20 +92,67 @@
    historyAlarmMapper.updateHistoryAlarm(alarmCode, historyAlarm);
  }
    /**
     * èŽ·å–åŽ†å²æŠ¥è­¦åˆ†é¡µæ•°æ®
     *
     * @param historyAlarm
     * @return
     */
  @Override
  public Page<JkHistoryAlarm> selectJkHistoryAlarmPage(JkHistoryAlarm jkHistoryAlarm, Long pageNum, Long pageSize) {
    final Page<JkHistoryAlarm> jkHistoryAlarmPage = historyAlarmMapper.selectJkHistoryAlarmPage(jkHistoryAlarm, new Page<>(pageNum, pageSize));
    jkHistoryAlarmPage.getRecords().forEach(alarm->{
      final String indexType = alarm.getIndexType();
      final String indexId = alarm.getIndexId();
      if("COLLECT".equals(indexType) && StringUtils.isEmpty(alarm.getEnergyId())){
        //根据nodeId和indexId åŽ»æŸ¥è¯¢è®¡é‡å™¨å…·
        EnergyIndex energyIndex = energyIndexMapper.selectEnergyIndexById(indexId);
        final MeterImplement meterImplement = meterImplementMapper.selectMeterImplementById(energyIndex.getMeterId());
        alarm.setEnergyId(meterImplement.getEnergyType());
    public Page<JkHistoryAlarm> selectHistoryAlarmPageList(JkHistoryAlarm historyAlarm) {
        Page<JkHistoryAlarm> pageInfo = PageUtils.getPageInfo(JkHistoryAlarm.class);
        List<String> indexIdList = new ArrayList<>();
        if ("ALL".equals(historyAlarm.getEierarchyFlag())) {
            ModelNode modelNode = modelNodeMapper.selectModelNodeById(historyAlarm.getNodeId());
            List<ModelNodeIndexInfo> modelNodeIndexInfoList =
                    modelNodeMapper.getAllModelNodeIndexByAddress(modelNode.getModelCode(), modelNode.getAddress());
            if (StringUtils.isNotEmpty(historyAlarm.getIndexName())) {
                modelNodeIndexInfoList = modelNodeIndexInfoList.stream()
                        .filter(modelNodeIndexInfo -> modelNodeIndexInfo.getIndexName().contains(historyAlarm.getIndexName()))
                        .collect(Collectors.toList());
      }
    });
    return jkHistoryAlarmPage;
            if (ObjectUtils.isNotEmpty(historyAlarm.getIndexType())) {
                modelNodeIndexInfoList = modelNodeIndexInfoList.stream()
                        .filter(modelNodeIndexInfo -> historyAlarm.getIndexType().equals(modelNodeIndexInfo.getIndexType()))
                        .collect(Collectors.toList());
            }
            indexIdList = modelNodeIndexInfoList.stream().map(ModelNodeIndexInfo::getIndexId).collect(Collectors.toList());
        } else {
            LambdaQueryWrapper<NodeIndex> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(NodeIndex::getNodeId, historyAlarm.getNodeId());
            List<NodeIndex> nodeIndexList = nodeIndexMapper.selectList(queryWrapper);
            List<String> allIndexIdList = nodeIndexList.stream().map(NodeIndex::getIndexId).collect(Collectors.toList());
            if (ObjectUtils.isNotEmpty(allIndexIdList)) {
                List<EnergyIndex> indexList = energyIndexMapper.selectEnergyIndexByIds(allIndexIdList);
                if (ObjectUtils.isNotEmpty(historyAlarm.getIndexName())) {
                    indexList = indexList.stream().filter(energyIndex -> energyIndex.getName().contains(historyAlarm.getIndexName())).collect(Collectors.toList());
                }
                if (ObjectUtils.isNotEmpty(historyAlarm.getIndexType())) {
                    indexList = indexList.stream().filter(energyIndex -> historyAlarm.getIndexType().equals(energyIndex.getIndexTypeCode())).collect(Collectors.toList());
                }
                indexIdList = indexList.stream().map(EnergyIndex::getIndexId).collect(Collectors.toList());
            }
        }
        if (ObjectUtils.isEmpty(indexIdList)) {
            return pageInfo;
        }
        //时间处理 å¦‚果不传时间默认查询当天的数据
        Date endTime = DateUtils.parseDate(historyAlarm.getEndTime());
        if (ObjectUtils.isEmpty(endTime)) {
            endTime = DateUtil.endOfDay(DateUtils.getNowDate());
        }
        Date beginTime = DateUtils.parseDate(historyAlarm.getBeginTime());
        if (ObjectUtils.isEmpty(beginTime)) {
            beginTime = DateUtil.beginOfDay(DateUtils.getNowDate());
        }
        return historyAlarmMapper.getHistoryAlarmList(beginTime, endTime,indexIdList, pageInfo);
  }
  
}
zhitan-system/src/main/java/com/zhitan/basicdata/domain/vo/MeterImplementModel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.zhitan.basicdata.domain.vo;
import lombok.Data;
@Data
public class MeterImplementModel {
    /**
     * indexId
     */
    private String indexId;
    /**
     * meterId
     */
    private String meterId;
    /**
     * èƒ½æºç±»åž‹
     */
    private String energyType;
}
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/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
@@ -1,6 +1,5 @@
package com.zhitan.comprehensivestatistics.mapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import org.apache.ibatis.annotations.Param;
@@ -29,7 +28,7 @@
                                                                  @Param("dataList") List<MonthlyComprehensive> dataList,
                                                                  @Param("beginTime") Date beginTime,
                                                                  @Param("endTime") Date endTime,
                                                                  @Param("timeType") TimeType timeType,
                                                                  @Param("timeType") String timeType,
                                                                  @Param("indexStorageId") String indexStorageId);
    /**
@@ -45,7 +44,7 @@
    List<MonthlyComprehensive> 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/YearComprehensiveMapper.java
@@ -1,6 +1,5 @@
package com.zhitan.comprehensivestatistics.mapper;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import org.apache.ibatis.annotations.Param;
@@ -29,7 +28,7 @@
                                                            @Param("dataList") List<YearComperhensive> dataList,
                                                            @Param("beginTime") Date beginTime,
                                                            @Param("endTime") Date endTime,
                                                            @Param("timeType") TimeType timeType,
                                                            @Param("timeType") String timeType,
                                                            @Param("indexStorageId") String indexStorageId);
    /**
@@ -45,7 +44,7 @@
    List<YearComperhensive> 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/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
@@ -1,7 +1,6 @@
package com.zhitan.comprehensivestatistics.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.MonthlyComprehensive;
import java.util.Date;
@@ -25,7 +24,7 @@
     * @param indexStorageId
     * @return
     */
    List<MonthlyComprehensive> getMonthlyComprehensiveList(String nodeId, List<MonthlyComprehensive> dataList, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<MonthlyComprehensive> getMonthlyComprehensiveList(String nodeId, List<MonthlyComprehensive> dataList, Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     * å…¨åŽ‚ç»¼åˆèƒ½è€—ç»Ÿè®¡ æœˆ
@@ -37,5 +36,5 @@
     * @param indexStorageId
     * @return
     */
    List<MonthlyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    List<MonthlyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, String timeType, String indexStorageId);
}
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/IyearComprehensive.java
@@ -1,7 +1,6 @@
package com.zhitan.comprehensivestatistics.service;
import com.zhitan.common.enums.TimeType;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import java.util.Date;
@@ -26,7 +25,7 @@
     * @return
     */
    List<YearComperhensive> getYearComprehensiveList(String nodeId, List<YearComperhensive> dataList,
                                                            Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
                                                            Date beginTime, Date endTime, String timeType, String indexStorageId);
    /**
     * èŽ·å–ç»¼åˆæŒ‡æ ‡åˆ†æžï¼ˆå¹´ï¼‰å›¾è¡¨æ•°æ®
@@ -38,5 +37,5 @@
     * @param indexStorageId
     * @return
     */
    List<YearComperhensive> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId);
    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
@@ -1,11 +1,9 @@
package com.zhitan.comprehensivestatistics.service.impl;
import com.zhitan.common.enums.TimeType;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -25,7 +23,7 @@
    private MonthlyComprehensiveMapper monthMapper;
    public List<MonthlyComprehensive> getMonthlyComprehensiveList(String nodeId, List<MonthlyComprehensive> dataList,
                                                                  Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
                                                                  Date beginTime, Date endTime, String timeType, String indexStorageId){
        if (StringUtils.isNotEmpty(nodeId)) {
            return monthMapper.getMonthlyComprehensiveList(nodeId, dataList, beginTime, endTime, timeType, indexStorageId);
        }
@@ -33,7 +31,7 @@
    }
    @Override
    public List<MonthlyComprehensive> getListChart(String indexId, Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
    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);
        }
zhitan-system/src/main/java/com/zhitan/comprehensivestatistics/service/impl/YearComprehensiveServiceImpl.java
@@ -2,7 +2,6 @@
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.enums.TimeType;
import com.zhitan.common.utils.DateTimeUtil;
import com.zhitan.comprehensivestatistics.domain.YearComperhensive;
import com.zhitan.comprehensivestatistics.mapper.YearComprehensiveMapper;
@@ -29,14 +28,14 @@
    @Override
    public List<YearComperhensive> getYearComprehensiveList(String nodeId, List<YearComperhensive> dataList,
                                                            Date beginTime, Date endTime, TimeType timeType, String indexStorageId){
                                                            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, TimeType timeType, String indexStorageId){
    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);
@@ -54,7 +53,7 @@
                    } else {
                        yearComperhensive.setTimeCode(format);
                        yearComperhensive.setIndexId(indexId);
                        yearComperhensive.setTimeType(timeType.name());
                        yearComperhensive.setTimeType(timeType);
                        yearComperhensive.setUnitId(first.getUnitId());
                        yearComperhensive.setIndexName(first.getIndexName());
                    }
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
@@ -126,6 +130,7 @@
    /**
     * æŸ¥è¯¢èƒ½æºç±»åž‹éžç”µçš„用量
     *
     * @param beginTime
     * @param endTime
     * @param timeType æ—¶é—´ç±»åž‹
@@ -135,4 +140,18 @@
     */
    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
@@ -3,6 +3,7 @@
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;
@@ -213,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/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/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/EnergyIndexMapper.java
@@ -2,8 +2,10 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhitan.basicdata.domain.vo.MeterImplementModel;
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 +91,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);
@@ -103,5 +105,7 @@
  List<EnergyIndex> getIndexByMeterIdIndexCode(@Param("meterId") String meterId, @Param("indexCode") String indexCode, @Param("nodeId") String nodeId);
  int deleteByIndexId(String indexId);
  List<ModelNodeIndexInfo> getModelNodeIndexInfoListByIndexIds(@Param("indexIds") String[] indexIds);
  List<MeterImplementModel> selectEnergyTypeByIndex(@Param("indexIds") List<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和能源类型查询点位下的累积量
@@ -215,4 +215,9 @@
                                                     @Param("energyType") String energyType,
                                                     @Param("timeType") TimeType timeType,
                                                     @Param("dateTimeMap") Map<String, LocalDateTime> dateTimeMap);
    /**
     * é€šè¿‡èŠ‚ç‚¹åœ°å€æŸ¥è¯¢èŠ‚ç‚¹ä¸‹åŠå­èŠ‚ç‚¹ä¸‹çš„æ‰€æœ‰ç‚¹ä½ä¿¡æ¯
     */
    List<ModelNodeIndexInfo> getAllModelNodeIndexByAddress(@Param("modelCode") String modelCode, @Param("address") String address);
}
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);
@@ -136,8 +137,9 @@
    List<EnergyIndex> listDeviceIndex(String nodeId, String meterId);
    /**
     * é€šè¿‡id删除采集点
     * æ ¹æ®ç‚¹ä½id获取模型节点点位信息
     * @param indexIds
     * @return
     */
    boolean deleteByIndexId(String indexId);
    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/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
@@ -362,10 +362,8 @@
        return energyIndexList;
    }
    @Override
    public boolean deleteByIndexId(String indexId) {
        return energyIndexMapper.deleteByIndexId(indexId) > 0;
    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/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,9 +130,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.HOUR.name());
@@ -312,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()
@@ -424,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/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;
@@ -32,7 +31,7 @@
  @ApiModelProperty(value = "时间类型编码")
  private String timeCode;
  @ApiModelProperty(value = "时间类型")
  private TimeType timeType;
  private String timeType;
  @ApiModelProperty(value = "值")
  private Double value;
  @ApiModelProperty(value = "质量")
@@ -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/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/statisticalAnalysis/domain/vo/FlowChartsVO.java
@@ -55,7 +55,8 @@
                || BigDecimal.ZERO.compareTo(difference) == 0){
            return BigDecimal.ZERO;
        }
        return energyLossRatio = difference.divide(totalAccumulatedAmount, 2, RoundingMode.HALF_UP);
        // å…ˆè®¡ç®—比例,再乘以 100 è½¬æ¢ä¸ºç™¾åˆ†æ•°
        return energyLossRatio = difference.divide(totalAccumulatedAmount, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
    }
    public FlowChartsVO() {
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/alarm/HistoryAlarmMapper.xml
@@ -4,7 +4,7 @@
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.alarm.mapper.HistoryAlarmMapper">
  <resultMap type="HistoryAlarm" id="HistoryAlarmResult">
  <resultMap type="com.zhitan.alarm.domain.HistoryAlarm" id="HistoryAlarmResult">
    <result property="id" column="id"/>
    <result property="endTime" column="end_time"/>
    <result property="indexId" column="index_id"/>
@@ -18,7 +18,7 @@
    <result property="content" column="content"/>
  </resultMap>
  <resultMap type="JkHistoryAlarm" id="JkHistoryAlarmResult">
  <resultMap type="com.zhitan.alarm.domain.JkHistoryAlarm" id="JkHistoryAlarmResult">
    <result property="modelName" column="modelname"/>
    <result property="code" column="code"/>
    <result property="indexName" column="indexname"/>
@@ -50,7 +50,7 @@
    from history_alarm
  </sql>
  <select id="selectHistoryAlarmList" parameterType="HistoryAlarm" resultMap="HistoryAlarmResult">
  <select id="selectHistoryAlarmList" parameterType="com.zhitan.alarm.domain.HistoryAlarm" resultMap="HistoryAlarmResult">
    <include refid="selectHistoryAlarmVo"/>
    <where>
      <if test="indexName != null  and indexName != ''">and index_name like concat('%',
@@ -77,7 +77,7 @@
  </select>
  <update id="updateHistoryAlarm" parameterType="HistoryAlarm">
  <update id="updateHistoryAlarm" parameterType="com.zhitan.alarm.domain.HistoryAlarm">
    delete from realtime_alarm where alarm_code = #{alarmCode};
    insert into history_alarm
    <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -127,7 +127,7 @@
  </delete>
  <!--历史 æŠ¥è­¦åˆ—表页面 é‡‡é›†ç‚¹ ä¸»é¡µé¢åˆ—表查询-->
  <select id="selectJkHistoryAlarmList" parameterType="JkHistoryAlarm"
  <select id="selectJkHistoryAlarmList" parameterType="com.zhitan.alarm.domain.JkHistoryAlarm"
    resultMap="JkHistoryAlarmResult">
    SELECT
    mo."name" AS modelname,
@@ -180,7 +180,7 @@
    order by alarm_level,mo.node_id,limit_type asc
  </select>
  <select id="selectJkHistoryAlarmListExcel" parameterType="JkHistoryAlarm"
  <select id="selectJkHistoryAlarmListExcel" parameterType="com.zhitan.alarm.domain.JkHistoryAlarm"
    resultMap="JkHistoryAlarmResult">
    SELECT
    mo."name" AS modelname,
@@ -232,7 +232,7 @@
    order by alarm_level,mo.node_id,limit_type asc
  </select>
  <select id="selectHistoryAlarmNoteList" parameterType="JkHistoryAlarm"
  <select id="selectHistoryAlarmNoteList" parameterType="com.zhitan.alarm.domain.JkHistoryAlarm"
    resultMap="JkHistoryAlarmResult">
    SELECT
    ei.code,
@@ -273,7 +273,7 @@
    </if>
    order by alarm_level,limit_type asc
  </select>
  <select id="selectJkHistoryAlarmPage" resultType="JkHistoryAlarm">
  <select id="selectJkHistoryAlarmPage" resultType="com.zhitan.alarm.domain.JkHistoryAlarm">
    SELECT
    mo."name" AS modelname,
    ei.code,
@@ -310,19 +310,24 @@
    AND alit.alarm_code = bj.alarm_code
    AND alit.time_slot='LIVE'
    AND ei.index_type=#{jkHistoryAlarm.indexType}
    <if test="jkHistoryAlarm.indexName != null  and jkHistoryAlarm.indexName != ''">and ei.name like concat('%', #{jkHistoryAlarm.indexName},
      '%')
    <if test="jkHistoryAlarm.indexName != null  and jkHistoryAlarm.indexName != ''">
      and ei.name like concat('%', #{jkHistoryAlarm.indexName}, '%')
    </if>
    <if test="jkHistoryAlarm.limitType != null  and jkHistoryAlarm.limitType != ''">and alit.limit_type=#{jkHistoryAlarm.limitType}</if>
    <if test="jkHistoryAlarm.alarmLevel != null  and jkHistoryAlarm.alarmLevel != ''">and alit.alarm_level=#{jkHistoryAlarm.alarmLevel}</if>
    <if test="jkHistoryAlarm.beginTime != null and jkHistoryAlarm.beginTime != ''">and begin_time &gt;=
      to_timestamp(#{jkHistoryAlarm.beginTime},'yyyy-mm-dd hh24:mi:ss')
    <if test="jkHistoryAlarm.limitType != null  and jkHistoryAlarm.limitType != ''">
      and alit.limit_type=#{jkHistoryAlarm.limitType}
    </if>
    <if test="jkHistoryAlarm.endTime != null and jkHistoryAlarm.endTime != ''">and begin_time &lt;=
      to_timestamp(#{jkHistoryAlarm.endTime},'yyyy-mm-dd hh24:mi:ss')
    <if test="jkHistoryAlarm.alarmLevel != null  and jkHistoryAlarm.alarmLevel != ''">
      and alit.alarm_level=#{jkHistoryAlarm.alarmLevel}
      </if>
    <if test="jkHistoryAlarm.beginTime != null and jkHistoryAlarm.beginTime != ''">
      and begin_time &gt;= to_timestamp(#{jkHistoryAlarm.beginTime}, 'yyyy-mm-dd hh24:mi:ss')
    </if>
    <if test="jkHistoryAlarm.endTime != null and jkHistoryAlarm.endTime != ''">
      and begin_time &lt;= to_timestamp(#{jkHistoryAlarm.endTime},'yyyy-mm-dd hh24:mi:ss')
    </if>
    order by alarm_level,mo.node_id,limit_type asc
  </select>
  <select id="selectCountByTime" resultType="java.lang.Integer">
    select count(0)
    from history_alarm 
@@ -333,7 +338,46 @@
      <if test="endTime != null ">
      and begin_time &lt;= #{endTime}
      </if>
      <if test="indexIdList != null and indexIdList.size() > 0">
        and index_id in
        <foreach collection="indexIdList" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
      </if>
    </where>
  </select>
    <select id="getHistoryAlarmList" resultType="com.zhitan.alarm.domain.JkHistoryAlarm">
      SELECT
        mn.node_id nodeId,
        mn."name" modelName,
        mi.meter_name meterName,
        mi.energy_type energyId,
        his.index_id indexId,
        ei."name" indexName,
        ei.index_type indexType,
        ei.code code,
        ei.unit_id unitId,
        ai.alarm_level alarmLevel,
        ai.limit_type limitType,
        his.limiting_value limitingValue,
        his.alarm_value alarmValue,
        his.begin_time alarmBeginTime,
        his.end_time alarmEndTime,
        his.duration duration
      FROM
        history_alarm his
          LEFT JOIN alarm_item ai ON his.item_id = ai."id"
          LEFT JOIN energy_index ei ON his.index_id = ei.index_id
          LEFT JOIN meter_implement mi ON ei.meter_id = mi."id"
          LEFT JOIN model_node mn ON mn.node_id = ai.node_id
      WHERE
        his.begin_time BETWEEN #{beginTime} AND #{endTime}
        <if test="indexIdList != null and indexIdList.size() > 0">
          AND his.index_id IN
          <foreach collection="indexIdList" item="item" open="(" separator="," close=")">
            #{item}
          </foreach>
        </if>
    </select>
</mapper>
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
@@ -46,6 +46,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>
@@ -56,6 +57,7 @@
            SELECT
                ni.index_id,
                ei."name" AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type,
@@ -75,7 +77,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/YearComprehensiveMapper.xml
@@ -27,6 +27,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>
@@ -37,6 +38,7 @@
            SELECT
                ni.index_id,
                ei."name" AS "index_name",
                ei.unit_id,
                di."value",
                di.data_time,
                di.time_type,
@@ -55,7 +57,7 @@
                and ei.energy_id=#{indexStorageId}
            </if>
        ) aa
        GROUP BY aa.index_id, aa.index_name, aa.time_type, aa.order_num
            GROUP BY 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/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
@@ -161,7 +161,7 @@
        WHEN di.time_type = 'DAY' THEN
        TO_CHAR( di.create_time, 'DD' )
        WHEN di.time_type = 'HOUR' THEN
        TO_CHAR( di.data_time, 'HH' )
        TO_CHAR( di.data_time, 'HH24' )
        ELSE TO_CHAR( di.data_time, 'YYMMDD' )
        END AS dataTimeStr,
            di.value,
@@ -233,4 +233,46 @@
        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/EnergyIndexMapper.xml
@@ -4,7 +4,7 @@
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.model.mapper.EnergyIndexMapper">
  <resultMap type="EnergyIndex" id="EnergyIndexResult">
    <resultMap type="com.zhitan.model.domain.EnergyIndex" id="EnergyIndexResult">
    <result property="indexId" column="index_id"/>
    <result property="name" column="name"/>
    <result property="code" column="code"/>
@@ -34,7 +34,8 @@
    from energy_index
  </sql>
  <select id="selectEnergyIndexList" parameterType="EnergyIndex" resultMap="EnergyIndexResult">
    <select id="selectEnergyIndexList" parameterType="com.zhitan.model.domain.EnergyIndex"
            resultMap="EnergyIndexResult">
    select ni.index_id, name, code, index_type, remark, unit_id, index_category
    from energy_index ei left join node_index ni on ei.index_id = ni.index_id
    <where>
@@ -59,7 +60,7 @@
    <include refid="selectEnergyIndexVo"/>
    where
        index_id IN
        <foreach collection="list" item="indexId" open="(" separator="," close=")">
        <foreach collection="indexIds" item="indexId" open="(" separator="," close=")">
          #{indexId}
        </foreach>
  </select>
@@ -145,7 +146,7 @@
    order by ei.order_num
  </select>
  <insert id="insertEnergyIndex" parameterType="EnergyIndex">
    <insert id="insertEnergyIndex" parameterType="com.zhitan.model.domain.EnergyIndex">
    insert into energy_index
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="indexId != null  and indexId != ''">index_id,</if>
@@ -187,7 +188,8 @@
  </insert>
  <insert id="insertNodeIndex">
    insert into node_index (node_id, index_id) values (#{nodeId}, #{indexId});
        insert into node_index (node_id, index_id)
        values (#{nodeId}, #{indexId});
  </insert>
  <insert id="insertEnergyIndices">
    <foreach collection="energyIndices" item="energyIndex" separator=";">
@@ -271,7 +273,7 @@
    </foreach>
  </insert>
  <update id="updateEnergyIndex" parameterType="EnergyIndex">
    <update id="updateEnergyIndex" parameterType="com.zhitan.model.domain.EnergyIndex">
    update energy_index
    <trim prefix="SET" suffixOverrides=",">
      <if test="name != null  and name != ''">name = #{name},</if>
@@ -303,16 +305,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>;
  </delete>
  <delete id="deleteByIndexId">
    delete
    from energy_index
    where index_id = #{indexId}
        </foreach>
  </delete>
  <select id="getEnergyIndexMeterByCodes" resultMap="EnergyIndexResult">
@@ -341,7 +338,8 @@
    select ni.index_id, name, code, index_type, remark, unit_id, index_category
    from energy_index ei left join node_index ni on ei.index_id = ni.index_id
    <where>
      <if test="query.codeOrName != null  and query.codeOrName != ''">and (name like concat('%', #{query.codeOrName},
            <if test="query.codeOrName != null  and query.codeOrName != ''">and (name like concat('%',
                #{query.codeOrName},
        '%') or code like concat('%', #{query.codeOrName}, '%'))
      </if>
      <if test="query.indexType != null">and index_type = #{query.indexType}</if>
@@ -413,4 +411,35 @@
        </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>
    <select id="selectEnergyTypeByIndex" resultType="com.zhitan.basicdata.domain.vo.MeterImplementModel">
        select ex.index_id indexId,
               mi.id meterId,
               mi.energy_type energyType
        from energy_index ex
                 left join meter_implement mi on ex.meter_id = mi.id
        where ex.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,
@@ -465,4 +466,22 @@
          AND di.data_time >= #{dateTimeMap.startTime}
          AND di.data_time &lt;= #{dateTimeMap.endTime}
    </select>
    <select id="getAllModelNodeIndexByAddress" resultType="com.zhitan.model.domain.vo.ModelNodeIndexInfo">
        SELECT
            mn.node_id nodeId,
            mn.code nodeCode,
            mn."name" nodeName,
            ni.index_id indexId,
            ei."name" indexName,
            ei.index_type indexType,
            mi.energy_type
        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
                LEFT JOIN meter_implement mi ON mi."id" = ei.meter_id
        WHERE
            mn.model_code = #{modelCode}
          AND mn.address LIKE concat( #{address} , '%' )
    </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,7 +5,5 @@
VITE_APP_ENV = 'development'
# ç³»ç»Ÿ/开发环境
# test
VITE_APP_BASE_API = '/dev-api'
# hangmingjun
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/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/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/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/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; /* é˜²æ­¢æ°´å¹³æ»šåŠ¨æ¡ */
}
*,
@@ -206,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,10 +51,64 @@
    }
    .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 {
@@ -84,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;
        }
      }
@@ -108,10 +211,56 @@
    .form-card {
      background: #fff;
      // background: #F7F8FA;
      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 {
@@ -159,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
@@ -394,7 +394,7 @@
  // æ ‘
  .el-tree {
    background: transparent;
    font-size: 16px;
    font-size: 14px;
    color: #ffffff;
    .el-tree-node__content {
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 {
@@ -92,7 +95,7 @@
      .menu-title {
        overflow: hidden !important;
        font-weight: 400 !important;
        font-size: 16px !important;
        font-size: 14px !important;
      }
      // @media (min-width: 1440px) {
@@ -191,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;
          }
        }
      }
@@ -284,7 +297,7 @@
.themeLight {
  #app {
    .el-menu-item.is-active {
      background: #e0eafc !important;
      // border-radius: 30px 30px 30px 30px !important;
    }
@@ -294,6 +307,7 @@
    }
    .main-container {
      background-color: #f7f8fa;
      height: 100%;
      transition: margin-left 0.28s;
      margin-left: $base-sidebar-width;
@@ -309,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;
@@ -377,7 +391,7 @@
      .menu-title {
        overflow: hidden !important;
        font-weight: 400 !important;
        font-size: 16px !important;
        font-size: 14px !important;
      }
      // @media (min-width: 1440px) {
@@ -478,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
@@ -67,6 +67,20 @@
      font-family: YouSheBiaoTiHei;
      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;
      }
    }
  }
zhitan-vue/src/components/BaseCard/index.vue
@@ -28,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;
        }
      }
    }
  }
@@ -46,6 +61,7 @@
    border: 1px solid #ebebeb;
    padding-bottom: 10px;
    background-color: #fff;
    .mycard-title {
      display: flex;
      justify-content: flex-start;
@@ -54,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
@@ -68,7 +68,7 @@
  console.log("initChart", series)
  let option = {
    title: {
      // text: props.chartData.title,
      text: props.chartData.title || "",
      left: "40",
      textStyle: {
        color: "#2979ff",
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: 52px;
    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: 32px;
        line-height: 30px;
        border: 1px solid #5278f5;
        color: #fff;
        // background: #3271eb;
        padding: 0 12px;
        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: 52px;
    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: 32px;
        line-height: 30px;
        border: 1px solid #d8dce5;
        color: #495060;
        background: #fff;
        padding: 0 12px;
        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','/social-callback']
/**
 * æŸ¥æ‰¾æœ€æ·±å±‚的子菜单并构建完整路径
 */
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: è·¯ç”±é…ç½®é¡¹
@@ -71,7 +72,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/views/alarmmanage/alarmrecord/alarmRecord.vue
@@ -70,7 +70,7 @@
                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="limitingValue" 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 />
            </el-table>
zhitan-vue/src/views/alarmmanage/measuremen/measuremen.vue
@@ -97,10 +97,13 @@
  timeType: null,
  dataTime: null,
  nodeId: null,
  modelCode: ''
})
import { getByNodeId, getCountInfo } from "@/api/alarmManage/alarmManage"
import { el } from "element-plus/es/locales.mjs"
import { useRoute } from "vue-router"
const route = useRoute()
let form = ref({})
let currentNode = ref()
@@ -114,6 +117,7 @@
  handleTimeType(period.value[0].value)
  getByNodeIdFun()
  getCountInfoFun()
}
function getByNodeIdFun() {
@@ -155,10 +159,12 @@
// getByNodeIdFun()
function handleQuery() {
  getByNodeIdFun()
  getCountInfoFun()
}
function resetQuery() {
  handleTimeType("YEAR")
  getByNodeIdFun()
  getCountInfoFun()
}
let dataArray = ref({
  indexCount: 0,
@@ -166,14 +172,16 @@
  monthCount: 0,
})
function getCountInfoFun() {
  getCountInfo(queryParams.value).then((res) => {
  getCountInfo({
    ...queryParams.value,
    modelCode: route.query.modelCode,
  }).then((res) => {
    if (res.code == 200) {
      dataArray.value = res.data
    }
  })
}
getCountInfoFun()
function pieChart(Id, data, name) {
  console.log(data)
  let total = 0
@@ -274,11 +282,11 @@
      axisPointer: {
        type: "shadow",
      },
      axisTick: {
        show: false,
        alignWithLabel: true,
        length: 5,
      },
      // axisTick: {
      //   show: false,
      //   alignWithLabel: true,
      //   length: 5,
      // },
      // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
      axisTick: {
        show: false,
@@ -313,11 +321,11 @@
        padding: [0, 0, 5, 0],
      },
      // åæ ‡è½´åˆ»åº¦
      axisTick: {
        show: false,
        alignWithLabel: true,
        length: 5,
      },
      // axisTick: {
      //   show: false,
      //   alignWithLabel: true,
      //   length: 5,
      // },
      // åæ ‡è½´åˆ»åº¦çº¿æ ·å¼
      axisTick: {
        show: false,
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/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/comprehensive/dailyComprehensive/index.vue
@@ -54,7 +54,7 @@
                  style="margin-right: 8px"
                ></el-button>
                <el-tooltip
                  v-if="scope.row.indexName.length > 9"
                  v-if="scope.row.indexName && scope.row.indexName.length > 9"
                  class="item"
                  effect="dark"
                  :content="scope.row.indexName"
zhitan-vue/src/views/comprehensive/monthlyComprehensive/index.vue
@@ -18,7 +18,7 @@
            v-model="queryParams.dataTime"
            type="month"
            :clearable="false"
            value-format="yyyy-MM"
            value-format="YYYY-MM"
            placeholder="选择日期"
          >
          </el-date-picker>
@@ -35,7 +35,7 @@
    <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 :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">
@@ -54,7 +54,7 @@
                  style="margin-right: 8px"
                ></el-button>
                <el-tooltip
                  v-if="scope.row.indexName.length > 9"
                  v-if="scope.row.indexName && scope.row.indexName.length > 9"
                  class="item"
                  effect="dark"
                  :content="scope.row.indexName"
@@ -68,7 +68,7 @@
              </div>
            </template>
          </el-table-column>
          <el-table-column v-for="index in 31" :key="index" :label="index + '日'" align="center" min-width="100">
          <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>
@@ -123,6 +123,7 @@
  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])
zhitan-vue/src/views/comprehensive/yearComprehensive/index.vue
@@ -54,7 +54,7 @@
                  style="margin-right: 8px"
                ></el-button>
                <el-tooltip
                  v-if="scope.row.indexName.length > 9"
                  v-if="scope.row.indexName && scope.row.indexName.length > 9"
                  class="item"
                  effect="dark"
                  :content="scope.row.indexName"
zhitan-vue/src/views/dataMonitoring/historyDataTrend/index.vue
@@ -210,6 +210,10 @@
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.page {
  background-color: #08234F;
}
.themeDark {
  .card-list {
    width: 100%;
zhitan-vue/src/views/deepanalysis/deepAnalysis.vue
@@ -18,15 +18,23 @@
          </el-select>
        </el-form-item>
        <el-form-item label="时间选择" prop="dataTime">
          <el-date-picker v-if="form.timeType == 'YEAR'" v-model="form.dataTime" type="year" />
          <el-date-picker v-if="form.timeType == 'YEAR'" v-model="form.dataTime" type="year" :clearable="false" />
          <el-date-picker
            v-else-if="form.timeType == 'MONTH'"
            v-model="form.dataTime"
            type="month"
            format="YYYY-MM"
            value-format="YYYY-MM"
            :clearable="false"
          />
          <el-date-picker v-else v-model="form.dataTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
          <el-date-picker
            v-else
            v-model="form.dataTime"
            :clearable="false"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -141,7 +149,8 @@
  getFlowCharts({
    energyType: form.value.energyType,
    nodeId: "",
    queryTime: form.value.dataTime,
    queryTime: proxy.dayjs(new Date(form.value.dataTime)).format("YYYY-MM-DD"),
    dataTime: proxy.dayjs(new Date(form.value.dataTime)).format("YYYY-MM-DD"),
    timeType: form.value.timeType,
    modelCode: proxy.$route.query.modelCode,
  }).then((res) => {
@@ -298,6 +307,7 @@
    display: flex;
    justify-content: space-between;
    padding-top: 12px;
    padding: 12px 14px 0;
    .card-list-item {
      width: 24%;
@@ -365,6 +375,7 @@
    display: flex;
    justify-content: space-between;
    padding-top: 12px;
    padding: 12px 14px 0;
    .card-list-item {
      width: 24%;
zhitan-vue/src/views/energy/energy.vue
@@ -1,6 +1,6 @@
<template>
  <div class="page">
    <HeaderCard :title="'恒邦能源数据综合分析'" />
    <HeaderCard :title="'能源数据综合分析'" />
    <div class="content-box">
      <div class="left-box">
        <BaseCardBaseCard title="当日能耗">
zhitan-vue/src/views/energyanalysis/equipment/equipment.vue
@@ -115,9 +115,10 @@
</template>
<script setup name="equipment">
import { listRegion, listDepartment } from "@/api/energyAnalysis/energyAnalysis"
import { listDepartment } from "@/api/energyAnalysis/energyAnalysis"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import * as echarts from "echarts"
import request from "@/utils/request"
const { proxy } = getCurrentInstance()
const { period } = proxy.useDict("period")
import { useRoute } from "vue-router"
@@ -183,12 +184,16 @@
  // }
  const myChart1 = echarts.init(document.getElementById("Chart1"))
  // const myChart2 = echarts.init(document.getElementById("Chart2"));
  listRegion(
    proxy.addDateRange({
  // ä¿®æ”¹ä¸ºç›´æŽ¥è°ƒç”¨consumptionanalysis/getByArea接口
  request({
    url: "/consumptionanalysis/getByArea",
    method: "get",
    params: proxy.addDateRange({
      ...queryParams.value,
      ...query.value,
    })
  ).then((res) => {
  }).then((res) => {
    if (!!res.code && res.code == 200) {
      loading.value = false
      let xdata = []
@@ -551,7 +556,7 @@
// èƒ½è€—对比分析-设备能耗分析-导出
function handleExport() {
  proxy.download(
    "consumptionanalysis/energyExport",
    "consumptionanalysis/getByArea/export",
    {
      ...queryParams.value,
      ...query.value,
zhitan-vue/src/views/index.vue
@@ -1,22 +1,27 @@
<template>
  <div class="page" style="padding-left: 8px; padding-top: 8px">
    <CardHeader :showBtn="true" :active="'0'" :period="period" @handleClick="handleTimeType">
      <span>
      <span class="card-header-title">
        å…¨åŽ‚èƒ½è€—ç»Ÿè®¡
        <el-button @click="dialogVisible = true" v-if="list.length > 1"> æŸ¥çœ‹æ›´å¤š </el-button>
        <el-button @click="dialogVisible = true" v-if="list.length > 1" type="primary" size="small" class="header-more-btn"> æŸ¥çœ‹æ›´å¤š </el-button>
      </span>
    </CardHeader>
    <template v-for="(row, rowIndex) in list" :key="rowIndex" v-loading="loading02">
      <div class="card-list" v-if="settingsStore.sideTheme == 'theme-dark' && rowIndex == 0">
        <template v-for="(item, index) in row" :key="index">
          <div
            class="card-list-item"
          <div class="card-list-item">
            <div class="item-left">
              <div class="top-icon"
            :style="{
              backgroundImage: 'url(' + bgList[index].bg + ')',
                  backgroundImage: 'url(' + bgList[index].icon + ')',
                  backgroundColor: bgList[index].iconBg,
                  width: '73px',
                  height: '73px',
                  backgroundSize: '40px'
            }"
          >
            <div class="item-top">
              <div class="top-icon" :style="{ backgroundImage: 'url(' + bgList[index].icon + ')' }" />
              />
            </div>
            <div class="item-right">
              <div class="top-right">
                <div class="right-name">
                  {{ item.energyName }}
@@ -24,28 +29,27 @@
                </div>
                <div class="right-value">
                  <span> {{ item.count }}</span>
                  <!-- <span class="unit">{{ item.energyUnit }}</span> -->
                </div>
              </div>
            </div>
            <div class="item-bottom">
              <div class="bottom-left">
                <span>
                  åŒæ¯”: {{ Math.abs(item.tongbi) }}
                  <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''">
                    åŒæ¯”: {{ Math.abs(item.tongbi).toFixed(1) }}
                    <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''">
                    <Top v-if="item.tongbi > 0" />
                    <Bottom v-if="item.tongbi < 0" />
                  </el-icon>
                </span>
              </div>
              <div class="bottom-right">
                <span
                  >环比: {{ Math.abs(item.huanbi) }}
                  <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''">
                  <span>
                    çŽ¯æ¯”: {{ Math.abs(item.huanbi).toFixed(1) }}
                    <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''">
                    <Top v-if="item.huanbi > 0" />
                    <Bottom v-if="item.huanbi < 0" />
                  </el-icon>
                </span>
                </div>
              </div>
            </div>
          </div>
@@ -54,36 +58,46 @@
      <div class="card-list" v-if="settingsStore.sideTheme != 'theme-dark' && rowIndex == 0">
        <template v-for="(item, index) in row" :key="index" v-show="rowIndex == 0">
          <div class="card-list-item">
            <div class="item-top">
              <div class="top-icon" :style="{ backgroundImage: 'url(' + bgList[index].icon2 + ')' }" />
            <div class="item-left">
              <div class="top-icon"
                :style="{
                  backgroundImage: 'url(' + bgList[index].icon2 + ')',
                  backgroundColor: bgList[index].iconBg,
                  width: '73px',
                  height: '73px',
                  backgroundSize: '40px'
                }"
              />
            </div>
            <div class="item-right">
              <div class="top-right">
                <div class="right-name">
                  {{ item.energyName }}
                  <span v-if="item.energyUnit" class="unit">({{ item.energyUnit }})</span>
                </div>
                <div class="right-value">
                  <span>{{ item.count }}</span>
                  <span class="unit">{{ item.energyUnit }}</span>
                </div>
              </div>
            </div>
            <div class="item-bottom">
              <div class="bottom-left">
                <span>
                  åŒæ¯”: {{ Math.abs(item.tongbi) }}
                  <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''">
                    åŒæ¯”: {{ Math.abs(item.tongbi).toFixed(1) }}
                    <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''">
                    <Top v-if="item.tongbi > 0" />
                    <Bottom v-if="item.tongbi < 0" />
                  </el-icon>
                </span>
              </div>
              <div class="bottom-right">
                <span
                  >环比: {{ Math.abs(item.huanbi) }}
                  <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''">
                  <span>
                    çŽ¯æ¯”: {{ Math.abs(item.huanbi).toFixed(1) }}
                    <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''">
                    <Top v-if="item.huanbi > 0" />
                    <Bottom v-if="item.huanbi < 0" />
                  </el-icon>
                </span>
                </div>
              </div>
            </div>
          </div>
@@ -133,66 +147,71 @@
        </el-col>
      </el-row>
    </div>
    <el-dialog v-model="dialogVisible" title="查看全厂能耗统计" width="80%" v-if="dialogVisible">
    <el-dialog v-model="dialogVisible" title="查看全厂能耗统计" width="90%" v-if="dialogVisible">
      <template v-for="(row, rowIndex) in list" :key="rowIndex">
        <div class="card-list" v-if="settingsStore.sideTheme == 'theme-dark'">
          <template v-for="(item, index) in row" :key="index">
            <div
              class="card-list-item"
              :style="{
                backgroundImage: 'url(' + bgList[index].bg + ')',
              }"
            >
              <div class="item-top">
                <div
                  class="top-icon"
            <div class="card-list-item">
              <div class="item-left">
                <div class="top-icon"
                  :style="{
                    backgroundImage: 'url(' + bgList[index].icon + ')',
                    backgroundColor: bgList[index].iconBg,
                    width: '73px',
                    height: '73px',
                    backgroundSize: '40px'
                  }"
                />
              </div>
              <div class="item-right">
                <div class="top-right">
                  <div class="right-name">
                    {{ item.energyName }}
                    <span v-if="item.energyUnit" class="unit">({{ item.energyUnit }})</span>
                  </div>
                  <div class="right-value">
                    <span> {{ item.count }}</span>
                    <span class="unit">{{ item.energyUnit }}</span>
                  </div>
                </div>
              </div>
              <div class="item-bottom">
                <div class="bottom-left">
                  <span>
                    åŒæ¯”: {{ Math.abs(item.tongbi) }}
                    <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''">
                      åŒæ¯”: {{ Math.abs(item.tongbi).toFixed(1) }}
                      <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''">
                      <Top v-if="item.tongbi > 0" />
                      <Bottom v-if="item.tongbi < 0" />
                    </el-icon>
                  </span>
                </div>
                <div class="bottom-right">
                  <span
                    >环比: {{ Math.abs(item.huanbi) }}
                    <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''">
                    <span>
                      çŽ¯æ¯”: {{ Math.abs(item.huanbi).toFixed(1) }}
                      <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''">
                      <Top v-if="item.huanbi > 0" />
                      <Bottom v-if="item.huanbi < 0" />
                    </el-icon>
                  </span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
        <div class="card-list" v-if="settingsStore.sideTheme != 'theme-dark'">
          <template v-for="(item, index) in row" :key="index" v-show="rowIndex == 0">
          <template v-for="(item, index) in row" :key="index">
            <div class="card-list-item">
              <div class="item-top">
                <div
                  class="top-icon"
              <div class="item-left">
                <div class="top-icon"
                  :style="{
                    backgroundImage: 'url(' + bgList[index].icon2 + ')',
                    backgroundColor: bgList[index].iconBg,
                    width: '73px',
                    height: '73px',
                    backgroundSize: '40px'
                  }"
                />
              </div>
              <div class="item-right">
                <div class="top-right">
                  <div class="right-name">
                    {{ item.energyName }}
@@ -202,21 +221,20 @@
                    <span class="unit">{{ item.energyUnit }}</span>
                  </div>
                </div>
              </div>
              <div class="item-bottom">
                <div class="bottom-left">
                  <span>
                    åŒæ¯”: {{ Math.abs(item.tongbi) }}
                    <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''">
                      åŒæ¯”: {{ Math.abs(item.tongbi).toFixed(1) }}
                      <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''">
                      <Top v-if="item.tongbi > 0" />
                      <Bottom v-if="item.tongbi < 0" />
                    </el-icon>
                  </span>
                </div>
                <div class="bottom-right">
                  <span
                    >环比: {{ Math.abs(item.huanbi) }}
                    <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''">
                    <span>
                      çŽ¯æ¯”: {{ Math.abs(item.huanbi).toFixed(1) }}
                      <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''">
                      <Top v-if="item.huanbi > 0" />
                      <Bottom v-if="item.huanbi < 0" />
                    </el-icon>
@@ -224,7 +242,7 @@
                </div>
              </div>
            </div>
            <div class="line"></div>
            </div>
          </template>
        </div>
      </template>
@@ -258,42 +276,47 @@
import index_card_3 from "@/assets/images/home/index-card-3.png"
import index_card_4 from "@/assets/images/home/index-card-4.png"
import index_card_5 from "@/assets/images/home/index-card-5.png"
import card_icon_1 from "@/assets/images/home/card-icon-1.png"
import card_icon_2 from "@/assets/images/home/card-icon-2.png"
import card_icon_3 from "@/assets/images/home/card-icon-3.png"
import card_icon_4 from "@/assets/images/home/card-icon-4.png"
import card_icon_5 from "@/assets/images/home/card-icon-5.png"
import card_icon2_1 from "@/assets/images/home/card-icon2-1.png"
import card_icon2_2 from "@/assets/images/home/card-icon2-2.png"
import card_icon2_3 from "@/assets/images/home/card-icon2-3.png"
import card_icon2_4 from "@/assets/images/home/card-icon2-4.png"
import card_icon2_5 from "@/assets/images/home/card-icon2-5.png"
import card_icon_1 from "@/assets/images/2.png"
import card_icon_2 from "@/assets/images/3.png"
import card_icon_3 from "@/assets/images/5.png"
import card_icon_4 from "@/assets/images/6.png"
import card_icon_5 from "@/assets/images/7.png"
import card_icon2_1 from "@/assets/images/2.png"
import card_icon2_2 from "@/assets/images/3.png"
import card_icon2_3 from "@/assets/images/5.png"
import card_icon2_4 from "@/assets/images/6.png"
import card_icon2_5 from "@/assets/images/7.png"
import { fa } from "element-plus/es/locales.mjs"
const bgList = ref([
  {
    bg: index_card_1,
    icon: card_icon_1,
    icon2: card_icon2_1,
    iconBg: "#3F7EE8"
  },
  {
    bg: index_card_2,
    icon: card_icon_2,
    icon2: card_icon2_2,
    iconBg: "#FFA024"
  },
  {
    bg: index_card_3,
    icon: card_icon_3,
    icon2: card_icon2_3,
    iconBg: "#FFCC00"
  },
  {
    bg: index_card_4,
    icon: card_icon_4,
    icon2: card_icon2_4,
    iconBg: "#3CC8D9"
  },
  {
    bg: index_card_5,
    icon: card_icon_5,
    icon2: card_icon2_5,
    iconBg: "#8833FF"
  },
])
const list = ref([[{}, {}, {}, {}, {}]])
@@ -857,10 +880,24 @@
}
</script>
<style scoped lang="scss">
.card-header-title {
  font-size: 18px;
  font-weight: bold;
  display: flex;
  align-items: center;
  .header-more-btn {
    margin-left: 12px;
    padding: 4px 10px;
    font-size: 12px;
    height: 28px;
  }
}
.themeDark {
  .page {
    padding: 20px;
    background: #120f2e;
    background: #05234A;
    .card-title {
      width: 132px;
@@ -873,54 +910,82 @@
    .card-list {
      margin-top: 14px;
      display: flex;
      // justify-content: space-between;
      width: 100%;
      flex-wrap: wrap;
      flex-wrap: nowrap;
      justify-content: space-between;
      gap: 15px;
      .card-list-item {
        width: 19%;
        margin-right: 1%;
        height: 157px;
        background-size: 100% 100%;
        box-sizing: border-box;
        padding: 25px 18px 12px 16px;
        color: #fff;
        .item-top {
          display: flex;
          .top-icon {
            width: 50px;
            height: 50px;
            background-size: 100% 100%;
      &:after {
        content: "";
        flex: 0 0 0;
          }
      .card-list-item {
        width: 0;
        flex: 1 1 320px;
        max-width: 320px;
        height: 135px;
        background: rgba(242, 246, 250, 0.1);
        box-sizing: border-box;
        padding: 16px;
        color: #fff;
        border-radius: 9px;
        box-shadow: none;
        border: none;
        display: flex;
        flex-direction: row;
        align-items: center;
        &:hover {
          background: rgba(242, 246, 250, 0.15);
        }
        .item-left {
          margin-right: 20px;
          .top-icon {
            width: 73px;
            height: 73px;
            background-size: 40px;
            background-repeat: no-repeat;
            background-position: center;
            border-radius: 50%;
          }
        }
        .item-right {
          flex: 1;
          display: flex;
          flex-direction: column;
          .top-right {
            margin-left: 12px;
            display: flex;
            flex-direction: column;
            .right-name {
              font-weight: bold;
              font-size: 16px;
              font-family: OPPOSans-Bold;
              font-weight: 400;
              font-size: 14px;
              font-family: OPPOSans-Regular;
              color: rgba(255, 255, 255, 0.65);
              letter-spacing: 0.5px;
              margin-bottom: 4px;
              .unit {
                margin-left: 2px;
                font-size: 16px;
                color: rgba(255, 255, 255, 0.65);
                margin-left: 4px;
                font-size: 12px;
                font-weight: normal;
              }
            }
            .right-value {
              font-weight: 800;
              font-size: 25px;
              margin-top: 10px;
              font-weight: 500;
              font-size: 26px;
              margin-top: 6px;
              font-family: OPPOSans-Medium;
              .unit {
                margin-left: 5px;
                font-size: 16px;
                font-weight: normal;
              }
            }
              color: #fff;
              line-height: 1.2;
              letter-spacing: 0.5px;
          }
        }
@@ -929,33 +994,52 @@
          justify-content: space-between;
          margin-top: 18px;
          font-family: OPPOSans, OPPOSans;
          font-weight: bold;
          font-size: 14px;
            font-weight: normal;
            font-size: 12px;
            color: rgba(255, 255, 255, 0.5);
            line-height: 1.2;
            .bottom-left, .bottom-right {
              display: flex;
              align-items: center;
              letter-spacing: 0.3px;
              :deep(.el-icon) {
                margin-left: 6px;
                font-size: 12px;
              }
            }
          }
        }
      }
    }
    .page-main {
      margin-top: 23px;
    }
  }
      margin-top: 20px;
  .chart {
    width: 100%;
    height: 292px;
    margin-top: 10px;
      .el-card {
        background-color: #0E2E5E;
        border: none;
        border-radius: 6px;
        :deep(.el-card__body) {
          padding: 12px;
        }
      }
  }
  .top-header {
    margin-top: 15px;
    height: 23px;
      margin-top: 12px;
      height: 32px;
    font-family: OPPOSans, OPPOSans;
    font-weight: 500;
    font-size: 14px;
    color: rgba(196, 213, 255, 0.6);
    border-bottom: 1px solid rgba(196, 213, 255, 0.6);
      color: rgba(255, 255, 255, 0.8);
      border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    display: flex;
    justify-content: space-between;
      align-items: center;
      padding: 0 10px;
    .header-left {
      display: flex;
@@ -965,72 +1049,128 @@
        margin-right: 7px;
      }
    }
    }
  }
  .chart {
    width: 100%;
    height: 292px;
    margin-top: 10px;
  }
  :deep(.el-button--primary) {
    background-color: #1976D2;
    border-color: #1976D2;
  }
  :deep(.el-card__header) {
    padding: 10px 15px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  }
  :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
    border-color: rgba(255, 255, 255, 0.1);
    background-color: transparent;
    color: #fff;
    &.is-active {
      background-color: #1976D2;
      border-color: #1976D2;
    }
  }
  :deep(.el-tabs--card > .el-tabs__header) {
    border-color: rgba(255, 255, 255, 0.1);
  }
}
.themeLight {
  .page {
    padding: 20px;
    background: #f7f8fa;
    background: #fff;
    .card-title {
      width: 132px;
      height: 29px;
      font-weight: bold;
      font-size: 22px;
      color: #ffffff;
      color: #333;
    }
    .card-list {
      width: 100%;
      margin-top: 14px;
      display: flex;
      // justify-content: space-between;
      align-items: center;
      background-image: url("@/assets/images/home/index-card-bg2.png");
      background-size: 100% 100%;
      flex-wrap: wrap;
      border-radius: 20px;
      width: 100%;
      flex-wrap: nowrap;
      justify-content: space-between;
      gap: 15px;
      &:after {
        content: "";
        flex: 0 0 0;
      }
      .card-list-item {
        width: 19%;
        margin-right: 0.5%;
        height: 157px;
        background-size: 100% 100%;
        width: 0;
        flex: 1 1 320px;
        max-width: 320px;
        height: 135px;
        background: #fff;
        box-sizing: border-box;
        padding: 25px 18px 12px 16px;
        color: #fff;
        .item-top {
        padding: 16px;
        color: #333;
        border-radius: 9px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
          display: flex;
        flex-direction: row;
        align-items: center;
        .item-left {
          margin-right: 20px;
          .top-icon {
            width: 69px;
            height: 69px;
            background-size: 100% 100%;
            width: 73px;
            height: 73px;
            background-size: 40px;
            background-repeat: no-repeat;
            background-position: center;
            border-radius: 50%;
          }
        }
        .item-right {
          flex: 1;
          display: flex;
          flex-direction: column;
          .top-right {
            margin-left: 16px;
            display: flex;
            flex-direction: column;
            .right-name {
              font-weight: bold;
              font-size: 16px;
              font-family: OPPOSans-Bold;
            }
            .right-value {
              font-weight: 800;
              font-size: 30px;
              margin-top: 10px;
              font-family: OPPOSans-Medium;
              font-weight: 400;
              font-size: 14px;
              font-family: OPPOSans-Regular;
              color: rgba(0, 0, 0, 0.65);
              letter-spacing: 0.5px;
              margin-bottom: 4px;
              .unit {
                margin-left: 5px;
                font-size: 16px;
                color: rgba(0, 0, 0, 0.65);
                margin-left: 4px;
                font-size: 12px;
                font-weight: normal;
              }
            }
            .right-value {
              font-weight: 500;
              font-size: 26px;
              margin-top: 6px;
              font-family: OPPOSans-Medium;
              color: #333;
              line-height: 1.2;
              letter-spacing: 0.5px;
          }
        }
@@ -1039,40 +1179,53 @@
          justify-content: space-between;
          margin-top: 18px;
          font-family: OPPOSans, OPPOSans;
          font-weight: bold;
          font-size: 14px;
        }
      }
            font-weight: normal;
            font-size: 12px;
            color: rgba(0, 0, 0, 0.5);
            line-height: 1.2;
      .line {
        width: 1px;
        height: 64px;
        background-image: url("@/assets/images/home/line@2x.png");
        background-size: 100% 100%;
            .bottom-left, .bottom-right {
              display: flex;
              align-items: center;
              letter-spacing: 0.3px;
              :deep(.el-icon) {
                margin-left: 6px;
                font-size: 12px;
              }
            }
          }
        }
      }
    }
    .page-main {
      margin-top: 23px;
    }
  }
      margin-top: 20px;
  .chart {
    width: 100%;
    height: 292px;
    margin-top: 10px;
      .el-card {
        background-color: #fff;
        border: none;
        border-radius: 6px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
        :deep(.el-card__body) {
          padding: 12px;
        }
      }
  }
  .top-header {
    margin-top: 15px;
    height: 23px;
      margin-top: 12px;
      height: 32px;
    font-family: OPPOSans, OPPOSans;
    font-weight: 500;
    font-size: 14px;
    color: rgba(29, 29, 29, 0.6);
    border-bottom: 1px solid rgba(196, 213, 255, 0.6);
      color: rgba(0, 0, 0, 0.6);
      border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    display: flex;
    justify-content: space-between;
      align-items: center;
      padding: 0 10px;
    .header-left {
      display: flex;
@@ -1084,4 +1237,35 @@
    }
  }
}
  .chart {
    width: 100%;
    height: 292px;
    margin-top: 10px;
  }
  :deep(.el-button--primary) {
    background-color: #1976D2;
    border-color: #1976D2;
  }
  :deep(.el-card__header) {
    padding: 10px 15px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  }
  :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
    border-color: rgba(0, 0, 0, 0.1);
    &.is-active {
      background-color: #1976D2;
      border-color: #1976D2;
      color: #fff;
    }
  }
  :deep(.el-tabs--card > .el-tabs__header) {
    border-color: rgba(0, 0, 0, 0.1);
  }
}
</style>
zhitan-vue/src/views/keyEquipment/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/keyEquipment/daily/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
<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.name" :value="item.id" v-for="item in facilityList" :key="item.id" />
          </el-select>
        </el-form-item> -->
        <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 { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import keyEquipmentApi from "@/api/keyEquipment/api"
import LineChart from "../comps/LineChart.vue"
let { proxy } = getCurrentInstance()
const facilityList = ref([])
function getEquip() {
  keyEquipmentApi.getPointFacility().then((res) => {
    facilityList.value = res.data
  })
}
getEquip()
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
  keyEquipmentApi
    .dailyList({
      ...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"
  keyEquipmentApi.dailyChart(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/keyEquipment/monthly/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
<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">
          <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="100">
            <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 keyEquipmentApi from "@/api/keyEquipment/api"
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
  keyEquipmentApi
    .monthlyList({
      ...queryParams.value,
    })
    .then((response) => {
      energyList.value = response.data
      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
  keyEquipmentApi.monthlyChart(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/keyEquipment/year/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<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="year"
            :clearable="false"
            value-format="YYYY"
            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">
          <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 12" :key="index" :label="index + '月'" align="center" min-width="100">
            <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/yearComprehensive/yearComprehensive"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import keyEquipmentApi from "@/api/keyEquipment/api"
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 queryParams = ref({
  indexStorageId: "",
  indexCode: "",
  pageNum: 1,
  pageSize: 10,
  dataTime: "2025-01-0",
  timeType: "MONTH",
})
const energyList = ref([])
const lineChartData = ref({})
function getList() {
  queryParams.value.indexCode = proxy.$route.query.modelCode
  keyEquipmentApi
    .yearList({
      ...queryParams.value,
      dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01" : "",
    })
    .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
  keyEquipmentApi
    .yearChart({
      ...queryParams.value,
      dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01" : "",
    })
    .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 + ""
}
// å¯¼å‡ºæŒ‰é’®æ“ä½œ
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: "MONTH",
  }
  getTime()
  getList()
}
getTime()
</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/login.vue
@@ -221,14 +221,15 @@
.login {
  display: flex;
  align-items: center;
  height: 100%;
  background-image: url("@/assets/images/login-background.jpg");
  height: 100vh;
  background-image: url("@/assets/images/login-background.png");
  background-repeat: no-repeat;
  background-size: cover;
  flex-direction: column;
  position: relative;
  min-width: 700px;
  min-height: 700px;
  background-color:#001146
}
.middle-view {
zhitan-vue/src/views/modelconfiguration/indexwarehouse/components/statisticalIndicatorManagement/statisticalIndicatorManagement.vue
@@ -2,7 +2,7 @@
  <div class="page-box">
    <div class="form-card">
      <el-form :model="form" ref="queryRef" :inline="true" label-width="70px">
        <el-form-item label="编码" prop="indexCategory">
        <el-form-item label="指标分类" prop="indexCategory">
          <el-select v-model="form.indexCategory" placeholder="请选择指标分类" style="width: 200px">
            <el-option v-for="dict in sys_index_category" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
zhitan-vue/src/views/poweranalysis/pariPassu/index.vue
@@ -156,7 +156,7 @@
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  handleTimeType(period.value[1].value)
  handleTimeType("MONTH")
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    queryParams.value.energyType = energyTypeList.value[0].enersno
@@ -168,11 +168,11 @@
function handleTimeType(e) {
  queryParams.value.timeType = e
  if (e == "MONTH") {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY-MM")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  } else if (e == "YEAR") {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  } else {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY-MM-DD")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  }
}
function handleEnergyType(item) {
@@ -200,6 +200,7 @@
    proxy.addDateRange({
      ...queryParams.value,
      ...query.value,
      timeCode: queryParams.value.dataTime,
    })
  ).then((res) => {
    if (!!res.code && res.code == 200) {
zhitan-vue/src/views/poweranalysis/perPassu/index.vue
@@ -156,7 +156,7 @@
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  handleTimeType(period.value[1].value)
  handleTimeType("MONTH")
  listEnergyTypeList().then((res) => {
    energyTypeList.value = res.data
    queryParams.value.energyType = energyTypeList.value[0].enersno
@@ -168,11 +168,11 @@
function handleTimeType(e) {
  queryParams.value.timeType = e
  if (e == "MONTH") {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY-MM")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  } else if (e == "YEAR") {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  } else {
    queryParams.value.timeCode = proxy.dayjs(new Date()).format("YYYY-MM-DD")
    queryParams.value.dataTime = proxy.dayjs(new Date()).format("YYYY-MM-DD")
  }
}
function handleEnergyType(item) {
@@ -200,6 +200,7 @@
    proxy.addDateRange({
      ...queryParams.value,
      ...query.value,
      timeCode: queryParams.value.dataTime,
    })
  ).then((res) => {
    if (!!res.code && res.code == 200) {
@@ -554,11 +555,11 @@
// èƒ½è€—对比分析-重置
function resetQuery() {
  proxy.resetForm("queryRef")
  handleTimeType(period.value[1].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 = "MOM"
  handleTimeType(period.value[1].value)
  handleQuery()
}
// èƒ½è€—对比分析-导出
zhitan-vue/src/views/processEnergy/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/processEnergy/daily/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
<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 { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import processApi from "@/api/process/api"
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
  processApi
    .dailyList({
      ...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"
  processApi.dailyChart(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/processEnergy/monthly/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<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">
          <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="100">
            <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 processApi from "@/api/process/api"
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
  processApi
    .monthlyList({
      ...queryParams.value,
      dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01" : "",
    })
    .then((response) => {
      energyList.value = response.data
      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
  processApi
    .monthlyChart({
      ...queryParams.value,
      dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01" : "",
    })
    .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
  console.log(queryParams.value.dataTime)
}
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/processEnergy/year/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<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="year"
            :clearable="false"
            value-format="YYYY"
            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">
          <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 12" :key="index" :label="index + '月'" align="center" min-width="100">
            <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/yearComprehensive/yearComprehensive"
import { listEnergyTypeList } from "@/api/modelConfiguration/energyType"
import processApi from "@/api/process/api"
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 queryParams = ref({
  indexStorageId: "",
  indexCode: "",
  pageNum: 1,
  pageSize: 10,
  dataTime: "2025-01-01",
  timeType: "MONTH",
})
const energyList = ref([])
const lineChartData = ref({})
function getList() {
  queryParams.value.indexCode = proxy.$route.query.modelCode
  processApi
    .yearList({
      ...queryParams.value,
      dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01" : "",
    })
    .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
  processApi
    .yearChart({
      ...queryParams.value,
      // dataTime: queryParams.value.dataTime ? queryParams.value.dataTime + "-01-01" : "",
    })
    .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 + ""
}
// å¯¼å‡ºæŒ‰é’®æ“ä½œ
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: "MONTH",
  }
  getTime()
  getList()
}
getTime()
</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/realtimemonitor/gatewaystatus/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,383 @@
<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">
          <div class="num">
            <div class="li name">{{ item.name }}</div>
            <div class="firstLi">
              <div :class="item.list.length < 16 ? 'li hasRightLine' : 'li'" v-for="(i, inde) in item.list" :key="inde">
                <div class="title_num" v-if="i.title_num">{{ i.title_num }}</div>
                <div class="dot" v-if="i.dot && i.dot.length > 0">
                  <div class="dot_li" v-for="(j, ind) in 3" :key="ind"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
let dataList = ref([
  {
    name: "网关",
    list: [
      {
        id: 1,
        title_num: "数据库",
        dot: [],
      },
      {
        id: 2,
        title_num: "200311",
        dot: [],
      },
      {
        id: 3,
        title_num: "200311",
        dot: [],
      },
      {
        id: 4,
        title_num: "200311",
        dot: [],
      },
      {
        id: 5,
        title_num: "200311",
        dot: [],
      },
      {
        id: 6,
        title_num: "200311",
        dot: [],
      },
      {
        id: 7,
        title_num: "200311",
        dot: [],
      },
      {
        id: 8,
        title_num: "200311",
        dot: [],
      },
      {
        id: 9,
        title_num: "200311",
        dot: [],
      },
      {
        id: 10,
        title_num: "200311",
        dot: [],
      },
      {
        id: 11,
        title_num: "200311",
        dot: [],
      },
      {
        id: 12,
        title_num: "200311",
        dot: [],
      },
      {
        id: 13,
        title_num: "200311",
        dot: [],
      },
      {
        id: 14,
        title_num: "200461",
        dot: [],
      },
      {
        id: 15,
        title_num: "200475",
        dot: [],
      },
    ],
  },
  {
    name: "计算器具",
    list: [
      {
        id: 1,
        title_num: "",
        dot: [
          {
            id: "001",
            dot_li: "",
          },
          {
            id: "002",
            dot_li: "",
          },
          {
            id: "003",
            dot_li: "",
          },
        ],
      },
      {
        id: 2,
        title_num: "",
        dot: [
          {
            id: "001",
            dot_li: "",
          },
          {
            id: "002",
            dot_li: "",
          },
        ],
      },
      {
        id: 3,
        title_num: "",
        dot: [
          {
            id: "001",
            dot_li: "",
          },
          {
            id: "002",
            dot_li: "",
          },
          {
            id: "003",
            dot_li: "",
          },
        ],
      },
    ],
  },
  {
    name: "网关",
    list: [
      {
        id: 1,
        title_num: "数据库",
        dot: [],
      },
      {
        id: 2,
        title_num: "200311",
        dot: [],
      },
      {
        id: 3,
        title_num: "200311",
        dot: [],
      },
      {
        id: 4,
        title_num: "200311",
        dot: [],
      },
    ],
  }
])
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.page {
  background: #08234F;
}
// æ ‡é¢˜æ ·å¼
.page-title {
  margin: 0 16px 16px;
  position: relative;
  .title-bar {
    position: relative;
    padding: 14px 0;
    padding-left: 16px;
    .title-text {
      font-size: 18px;
      font-weight: 600;
      position: relative;
      padding-left: 12px;
      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: -10px;
    left: 0;
    width: 100%;
    height: 1px;
    background-color: #E6E6E6;
  }
}
.themeDark {
  .table-box {
    margin: 10px 25px;
    .border {
      border: 1px solid #22408c;
      border-radius: 8px;
      background: #1a235d;
      padding: 10px 0;
      .table {
        margin: 15px;
        // border: 1px solid #22408c;
        .num {
          height: 56px;
          display: flex;
        }
        .li {
          height: 56px;
          padding: 0 10px;
          min-width: 60px;
          display: flex;
          flex-direction: column;
          justify-content: space-evenly;
          align-items: center;
          border-top: 1px solid #22408c;
          border-left: 1px solid #22408c;
          border-bottom: 1px solid #22408c;
          position: relative;
        }
        .hasRightLine {
          border-right: 1px solid #22408c;
        }
        .name {
          width: 80px;
          background: #1a235d;
          color: rgba(255, 255, 255, 0.8);
          text-align: center;
          font-family: OPPOSans, OPPOSans;
          font-weight: 500;
          font-size: 16px;
        }
        .title_num {
          color: #eeeeee;
          font-family: OPPOSans, OPPOSans;
          font-weight: 500;
          font-size: 16px;
        }
        .dot {
          display: flex;
          flex-direction: column;
          // justify-content: space-evenly;
          height: 30px;
          width: 12px;
          align-items: center;
        }
        .dot_li {
          height: 8px;
          width: 8px;
          margin: 2px 0;
          background: red;
          border-radius: 50%;
        }
        .firstLi {
          display: flex;
          flex: 1;
        }
      }
    }
  }
}
.themeLight {
  .table-box {
    margin: 10px 25px;
    .border {
      border: 1px solid #ebebeb;
      border-radius: 8px;
      background: #fff;
      padding: 10px 0;
      .table {
        margin: 15px;
        // border: 1px solid #22408c;
        .num {
          height: 56px;
          display: flex;
        }
        .li {
          height: 56px;
          padding: 0 10px;
          min-width: 60px;
          display: flex;
          flex-direction: column;
          justify-content: space-evenly;
          align-items: center;
          border-top: 1px solid #ebebeb;
          border-left: 1px solid #ebebeb;
          border-bottom: 1px solid #ebebeb;
          position: relative;
        }
        .hasRightLine {
          border-right: 1px solid #ebebeb;
        }
        .name {
          width: 80px;
          background: #fff;
          color: #0d0d0d;
          text-align: center;
          font-family: OPPOSans, OPPOSans;
          font-weight: 500;
          font-size: 16px;
        }
        .title_num {
          color: #0d0d0d;
          font-family: OPPOSans, OPPOSans;
          font-weight: 500;
          font-size: 16px;
        }
        .dot {
          display: flex;
          flex-direction: column;
          // justify-content: space-evenly;
          height: 30px;
          width: 12px;
          align-items: center;
        }
        .dot_li {
          height: 8px;
          width: 8px;
          margin: 2px 0;
          background: red;
          border-radius: 50%;
        }
        .firstLi {
          display: flex;
          flex: 1;
        }
      }
    }
  }
}
</style>
zhitan-vue/src/views/realtimemonitor/realtimemonitor/realtimemonitor.vue
@@ -2,7 +2,7 @@
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" />
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" ParentModelCode="YSCJMX" />
      </div>
      <div class="page-container-right">
        <div class="form-card">
@@ -207,8 +207,8 @@
      text-align: left;
      font-weight: bold;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      font-size: 14px;
      font-style: normal;
      text-transform: none;
    }
@@ -233,8 +233,8 @@
      .title {
        color: rgba(255, 255, 255, 0.8);
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        font-size: 16px;
        font-size: 14px;
        line-height: 19px;
        text-align: left;
        font-style: normal;
@@ -242,7 +242,7 @@
      }
      .num {
        font-size: 24px;
        font-size: 26px;
        color: #36d3ff;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
@@ -292,7 +292,7 @@
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 10px;
      padding: 2px 6px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
@@ -349,7 +349,7 @@
      }
      .num {
        font-size: 24px;
        font-size: 26px;
        color: #3271eb;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
@@ -399,7 +399,7 @@
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 3px;
      padding: 2px 6px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
@@ -431,7 +431,7 @@
  text-align: center;
  margin: 2px 6px;
  border-radius: 8px;
  padding: 5px 10px;
  padding: 2px 6px;
  font-family: OPPOSans, OPPOSans;
  font-weight: 500;
  font-size: 14px;
zhitan-vue/src/views/register.vue
@@ -160,7 +160,7 @@
  justify-content: center;
  align-items: center;
  height: 100%;
  background-image: url("../assets/images/login-background.jpg");
  background-image: url("../assets/images/login-background.png");
  background-size: cover;
}
.title {
zhitan-vue/src/views/system/name/name.vue
@@ -1,30 +1,30 @@
<template>
  <div class="app-container page">
    <div class="form-card">
      <el-form :model="form" label-width="80px">
        <el-row class="mb20 mt20">
          <el-col :offset="1" :span="18">
  <div class="app-container page name-settings-page">
    <div class="name-settings-card">
      <el-form :model="form" label-width="120px">
        <el-row class="form-row">
          <el-col :span="18">
            <el-form-item label="系统名称" prop="systemName">
              <el-input v-model="form.systemName" placeholder="请输入系统名称" maxlength="64" show-word-limit />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row class="mb20 mt20">
          <el-col :offset="1" :span="18">
        <el-row class="form-row">
          <el-col :span="18">
            <el-form-item label="登录logo" prop="homeLogo">
              <ImageUpload v-model="form.homeLogo" :fileType="['png']" :limit="1" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row class="mb20 mt20">
          <el-col :offset="1" :span="18">
        <el-row class="form-row">
          <el-col :span="18">
            <el-form-item label="后台logo" prop="leftLogo">
              <ImageUpload v-model="form.leftLogo" :fileType="['png']" :limit="1" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row class="mb20 mt20">
          <el-col :offset="1" :span="18">
        <el-row class="form-row">
          <el-col :span="18">
            <el-form-item label="copyRight" prop="copyRight">
              <el-input
                v-model="form.copyRight"
@@ -37,9 +37,11 @@
            </el-form-item>
          </el-col>
        </el-row>
        <el-row class="mb20 mt20" style="padding-bottom: 20px">
          <el-col :offset="2" :span="18">
        <el-row class="form-row form-footer">
          <el-col :span="18">
            <el-form-item>
            <el-button type="primary" @click="handleSave">保存</el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
@@ -68,6 +70,11 @@
}
getSystemName()
function handleSave() {
  if (!form.value.leftLogo || !form.value.homeLogo) {
    proxy.$modal.msgError("请上传logo")
    return
  }
  if (!form.value.leftLogo.includes(baseUrl)) {
    form.value.leftLogo = baseUrl + form.value.leftLogo
  }
@@ -87,7 +94,51 @@
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
:deep .avatar-uploader .el-upload {
.name-settings-page {
  height: 100%;
  min-height: calc(100vh - 60px);
  display: flex;
  flex-direction: column;
}
.name-settings-card {
  border-radius: 4px;
  margin: 16px;
  padding: 24px;
  flex: 1;
  height: calc(100vh - 100px);
  overflow-y: auto;
  .el-form {
    width: 100%;
    .form-row {
      margin-bottom: 24px;
      &.form-footer {
        margin-top: 40px;
      }
    }
    .el-form-item {
      margin-bottom: 0;
      .el-form-item__label {
        color: var(--el-text-color-primary, #fff);
      }
      .el-form-item__content {
        .el-button {
          padding: 10px 24px;
        }
      }
    }
  }
}
:deep(.avatar-uploader .el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
@@ -96,11 +147,11 @@
  transition: var(--el-transition-duration-fast);
}
:deep .avatar-uploader .el-upload:hover {
:deep(.avatar-uploader .el-upload:hover) {
  border-color: var(--el-color-primary);
}
:deep .el-icon.avatar-uploader-icon {
:deep(.el-icon.avatar-uploader-icon) {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
zhitan-vue/src/views/system/user/profile/index.vue
@@ -1,5 +1,5 @@
<template>
  <div class="app-container">
  <div class="app-container user-profile-container">
    <el-row :gutter="20">
      <el-col :span="6" :xs="24">
        <el-card class="box-card">
zhitan-vue/vite.config.js
@@ -35,7 +35,12 @@
        "/dev-api": {
          target: "http://localhost:8080",
          changeOrigin: true,
          rewrite: (p) => p.replace(/^\/dev-api/, ""),
          rewrite: (p) => p.replace(/^\/dev-api/, "/"),
        },
        "/prod-api": {
          target: "http://localhost:8080",
          changeOrigin: true,
          secure: true,
        },
      },
    },