@ -1,24 +1,34 @@
package com.mh.system.service.energy.impl ;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper ;
import com.mh.common.core.domain.AjaxResult ;
import com.mh.common.core.domain.dto.EnergyConsumptionDTO ;
import com.mh.common.core.domain.dto.EnergyStructureDTO ;
import com.mh.common.core.domain.entity.CollectionParamsManage ;
import com.mh.common.core.domain.entity.ConsumptionAnalyze ;
import com.mh.common.core.domain.entity.SysDictData ;
import com.mh.common.core.domain.entity.SysParams ;
import com.mh.common.core.domain.vo.EnergyQueryVO ;
import com.mh.common.utils.DateUtils ;
import com.mh.common.utils.EnergyThreadPoolService ;
import com.mh.system.mapper.SysDictDataMapper ;
import com.mh.system.mapper.SysParamsMapper ;
import com.mh.system.mapper.device.CollectionParamsManageMapper ;
import com.mh.system.mapper.energy.ComprehensiveEnergyConsumptionMapper ;
import com.mh.system.mapper.energy.EnergyMapper ;
import com.mh.system.mapper.energy.EnergyQueryMapper ;
import com.mh.system.service.energy.IComprehensiveEnergyConsumptionService ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.stereotype.Service ;
import java.math.BigDecimal ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.* ;
import java.util.concurrent.CountDownLatch ;
import java.util.concurrent.ExecutionException ;
import java.util.concurrent.Future ;
import java.util.concurrent.ThreadPoolExecutor ;
import java.util.concurrent.atomic.AtomicReference ;
import java.util.stream.Collectors ;
/ * *
* @author LJF
@ -27,6 +37,7 @@ import java.util.Map;
* @description 综合能耗结构服务实现
* @date 2025 - 03 - 24 15 : 57 : 09
* /
@Slf4j
@Service
public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensiveEnergyConsumptionService {
@ -38,11 +49,98 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
private final SysParamsMapper sysParamsMapper ;
public ComprehensiveEnergyConsumptionServiceImpl ( CollectionParamsManageMapper collectionParamsManageMapper , ComprehensiveEnergyConsumptionMapper comprehensiveEnergyConsumptionMapper , SysDictDataMapper sysDictDataMapper , SysParamsMapper sysParamsMapper ) {
private final EnergyQueryMapper energyQueryMapper ;
public ComprehensiveEnergyConsumptionServiceImpl ( CollectionParamsManageMapper collectionParamsManageMapper ,
ComprehensiveEnergyConsumptionMapper comprehensiveEnergyConsumptionMapper ,
SysDictDataMapper sysDictDataMapper ,
SysParamsMapper sysParamsMapper ,
EnergyQueryMapper energyQueryMapper ) {
this . collectionParamsManageMapper = collectionParamsManageMapper ;
this . comprehensiveEnergyConsumptionMapper = comprehensiveEnergyConsumptionMapper ;
this . sysDictDataMapper = sysDictDataMapper ;
this . sysParamsMapper = sysParamsMapper ;
this . energyQueryMapper = energyQueryMapper ;
}
@Override
public List < ? > drilling ( EnergyQueryVO vo ) {
DateUtils . sysEnergyDateChange ( vo ) ;
// 获取参数
AtomicReference < String > lastTableName = new AtomicReference < > ( "data_" + vo . getTimeType ( ) ) ;
AtomicReference < String > curTableName = new AtomicReference < > ( "data_" + vo . getTimeType ( ) ) ;
String timeType = vo . getTimeType ( ) ;
// 判断是否有总表
boolean haveMeter = collectionParamsManageMapper . selectSummary ( 40 , "5" ) ! = 0 ;
boolean haveCloud = collectionParamsManageMapper . selectSummary ( 40 , "6" ) ! = 0 ;
List < ConsumptionAnalyze > consumptionAnalyzeEntities = null ;
// 表格数据
if ( "month" . equalsIgnoreCase ( timeType ) | | "year" . equalsIgnoreCase ( timeType ) ) {
// 单表
consumptionAnalyzeEntities = energyQueryMapper . queryOneTable ( vo . getStartTime ( ) , vo . getEndTime ( ) , lastTableName . get ( ) , curTableName . get ( ) , DateUtils . getTimeLen ( vo . getTimeType ( ) ) , vo . getParamType ( ) , haveMeter , haveCloud , vo . getSystemType ( ) ) ;
} else {
lastTableName . set ( lastTableName + vo . getStartTime ( ) . substring ( 0 , 4 ) ) ;
curTableName . set ( curTableName + vo . getEndTime ( ) . substring ( 0 , 4 ) ) ;
if ( lastTableName . get ( ) . equalsIgnoreCase ( curTableName . get ( ) ) ) {
// 单表
consumptionAnalyzeEntities = energyQueryMapper . queryOneTable ( vo . getStartTime ( ) , vo . getEndTime ( ) , lastTableName . get ( ) , curTableName . get ( ) , DateUtils . getTimeLen ( vo . getTimeType ( ) ) , vo . getParamType ( ) , haveMeter , haveCloud , vo . getSystemType ( ) ) ;
} else {
// 多表
consumptionAnalyzeEntities = energyQueryMapper . queryManyTable ( vo . getStartTime ( ) , vo . getEndTime ( ) , lastTableName . get ( ) , curTableName . get ( ) , DateUtils . getTimeLen ( vo . getTimeType ( ) ) , vo . getParamType ( ) , haveMeter , haveCloud , vo . getSystemType ( ) ) ;
}
}
if ( null = = consumptionAnalyzeEntities | | consumptionAnalyzeEntities . size ( ) = = 0 ) {
return List . of ( ) ;
}
// 分组并按时间排序操作,拿到冷量记和电表数据
Map < String , List < ConsumptionAnalyze > > collect = consumptionAnalyzeEntities . stream ( )
. parallel ( )
. collect ( Collectors . groupingBy ( ConsumptionAnalyze : : getDeviceType , HashMap : : new , Collectors
. collectingAndThen ( Collectors . toList ( ) ,
list - > list . stream ( ) . sorted ( Comparator . comparing ( ConsumptionAnalyze : : getTimeStr ) ) . collect ( Collectors . toList ( ) ) ) ) ) ;
List < ConsumptionAnalyze > meterData = new ArrayList < > ( ) ;
for ( Map . Entry < String , List < ConsumptionAnalyze > > nmap : collect . entrySet ( ) ) {
// 获取电表的值
if ( nmap . getKey ( ) . equalsIgnoreCase ( "meter" ) ) {
meterData = nmap . getValue ( ) ;
}
}
String [ ] timeStrArr = meterData . stream ( )
. map ( ConsumptionAnalyze : : getTimeStr )
. toArray ( String [ ] : : new ) ;
String [ ] meterArr = meterData . stream ( )
. map ( ConsumptionAnalyze : : getCurValue )
. toArray ( String [ ] : : new ) ;
// 表格数据
Map < String , Object > map = new HashMap < > ( ) ;
int pageNum = vo . getPageNum ( ) ;
int pageSize = vo . getPageSize ( ) ;
if ( pageNum = = 0 ) {
map . put ( "meterArr" , meterArr ) ;
map . put ( "timeStrArr" , timeStrArr ) ;
} else {
int startIndex = ( pageNum - 1 ) * pageSize ;
int endIndex = Math . min ( pageNum * pageSize , meterArr . length ) ;
if ( startIndex > endIndex ) {
return List . of ( ) ;
}
map . put ( "meterArr" , Arrays . copyOfRange ( meterArr , startIndex , endIndex ) ) ;
map . put ( "timeStrArr" , Arrays . copyOfRange ( timeStrArr , startIndex , endIndex ) ) ;
}
// 组装赋值
List < Map < String , Object > > listData = new ArrayList < > ( ) ;
Map < String , Object > meter = new HashMap < > ( ) ;
meter . put ( "meter" , map . get ( "meterArr" ) ) ;
listData . add ( meter ) ;
String [ ] titleArr = new String [ ] { "meter" } ;
Map < String , Object > titles = new HashMap < > ( ) ;
titles . put ( "titleArr" , titleArr ) ;
listData . add ( titles ) ;
Map < String , Object > timeStr = new HashMap < > ( ) ;
timeStr . put ( "timeStrArr" , map . get ( "timeStrArr" ) ) ;
listData . add ( timeStr ) ;
return List . of ( listData ) ;
}
@Override
@ -85,13 +183,13 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
// 流式拼接数据,根据map的deviceType,systemType两个分组拼接数据,得出deviceType, systemType, curValue, yoyValue, hbyValue
// 得出新map,计算同比环比
for ( Map < String , Object > map : structData ) {
String deviceType = map . get ( "deviceType " ) . toString ( ) ;
String deviceType = map . get ( "label " ) . toString ( ) ;
String systemType = map . get ( "systemType" ) . toString ( ) ;
// 当前值
map . put ( "curValue" , map . get ( "calcValue" ) = = null ? 0 : map . get ( "calcValue" ) ) ;
// 同比值
map . put ( "yoyValue" , yoyStructData . stream ( )
. filter ( item - > item . get ( "deviceType " ) . equals ( deviceType )
. filter ( item - > item . get ( "label " ) . equals ( deviceType )
& & item . get ( "systemType" ) . equals ( systemType ) )
. findFirst ( )
. map ( item - > item . get ( "calcValue" ) = = null ? 0 : item . get ( "calcValue" ) )
@ -100,12 +198,12 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
// 同比率计算
BigDecimal curValue = new BigDecimal ( String . valueOf ( map . get ( "curValue" ) ) ) ;
BigDecimal yoyValue = new BigDecimal ( String . valueOf ( map . get ( "yoyValue" ) ) ) ;
map . put ( "yoyRate" , cur Value. compareTo ( BigDecimal . ZERO ) = = 0 ? BigDecimal . ZERO
: yoyValue . divide ( curValue , 2 , BigDecimal . ROUND_HALF_UP ) ) ;
map . put ( "yoyRate" , yoy Value. compareTo ( BigDecimal . ZERO ) = = 0 ? BigDecimal . ZERO
: ( curValue . subtract ( yoyValue ) ) . divide ( yoyValue ) . multiply ( new BigDecimal ( 100 ) ) . setScale ( 2 , BigDecimal . ROUND_HALF_UP ) ) ;
// 环比值
map . put ( "momValue" , hbyStructData . stream ( )
. filter ( item - > item . get ( "deviceType " ) . equals ( deviceType )
. filter ( item - > item . get ( "label " ) . equals ( deviceType )
& & item . get ( "systemType" ) . equals ( systemType ) )
. findFirst ( )
. map ( item - > item . get ( "calcValue" ) = = null ? 0 : item . get ( "calcValue" ) )
@ -113,8 +211,8 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
// 环比率计算
BigDecimal momValue = new BigDecimal ( String . valueOf ( map . get ( "momValue" ) ) ) ;
map . put ( "momRate" , cur Value. compareTo ( BigDecimal . ZERO ) = = 0 ? BigDecimal . ZERO
: momValue . divide ( curValue , 2 , BigDecimal . ROUND_HALF_UP ) ) ;
map . put ( "momRate" , mom Value. compareTo ( BigDecimal . ZERO ) = = 0 ? BigDecimal . ZERO
: ( curValue . subtract ( momValue ) ) . divide ( momValue ) . multiply ( new BigDecimal ( 100 ) ) . setScale ( 2 , BigDecimal . ROUND_HALF_UP ) ) ;
}
energyStructureDTO . setChildren ( structData ) ;
@ -122,10 +220,79 @@ public class ComprehensiveEnergyConsumptionServiceImpl implements IComprehensive
result1 . add ( energyStructureDTO ) ;
}
result . setChildren ( result1 ) ;
// 得出结果,然后通过递归计算children上一层级的值,比如result的children,可以计算出result的curValue,yoyValue,momValue,yoyRate,momRate赋值给result对应值
calculateParentValues ( result ) ;
// 查询各个设备的能耗结构
return List . of ( result ) ;
}
private void calculateParentValues ( EnergyStructureDTO result ) {
if ( result . getChildren ( ) = = null | | result . getChildren ( ) . isEmpty ( ) ) {
return ; // 如果没有子节点,直接返回
}
double curValueSum = 0 ;
double yoyValueSum = 0 ;
double momValueSum = 0 ;
// 遍历所有子节点,累加各个值
for ( Object child : result . getChildren ( ) ) {
if ( child instanceof Map ) {
Map < String , Object > childMap = ( Map < String , Object > ) child ;
// 判断 curValue 是否为空
if ( childMap . get ( "curValue" ) ! = null ) {
curValueSum + = Double . parseDouble ( childMap . get ( "curValue" ) . toString ( ) ) ;
}
// 判断 yoyValue 是否为空
if ( childMap . get ( "yoyValue" ) ! = null ) {
yoyValueSum + = Double . parseDouble ( childMap . get ( "yoyValue" ) . toString ( ) ) ;
}
// 判断 momValue 是否为空
if ( childMap . get ( "momValue" ) ! = null ) {
momValueSum + = Double . parseDouble ( childMap . get ( "momValue" ) . toString ( ) ) ;
}
} else if ( child instanceof EnergyStructureDTO ) {
calculateParentValues ( ( EnergyStructureDTO ) child ) ; // 递归计算子节点的值
// 判断 curValue 是否为空
if ( ( ( EnergyStructureDTO ) child ) . getCurValue ( ) ! = null ) {
curValueSum + = ( ( EnergyStructureDTO ) child ) . getCurValue ( ) . doubleValue ( ) ;
}
// 判断 yoyValue 是否为空
if ( ( ( EnergyStructureDTO ) child ) . getYoyValue ( ) ! = null ) {
yoyValueSum + = ( ( EnergyStructureDTO ) child ) . getYoyValue ( ) . doubleValue ( ) ;
}
// 判断 momValue 是否为空
if ( ( ( EnergyStructureDTO ) child ) . getMomValue ( ) ! = null ) {
momValueSum + = ( ( EnergyStructureDTO ) child ) . getMomValue ( ) . doubleValue ( ) ;
}
}
}
// 设置当前节点的值
result . setCurValue ( BigDecimal . valueOf ( curValueSum ) ) ;
result . setYoyValue ( BigDecimal . valueOf ( yoyValueSum ) ) ;
result . setMomValue ( BigDecimal . valueOf ( momValueSum ) ) ;
// 计算同比和环比增长率
if ( result . getYoyValue ( ) . compareTo ( BigDecimal . ZERO ) ! = 0 ) {
result . setYoyRate ( ( result . getCurValue ( ) . subtract ( result . getYoyValue ( ) ) )
. divide ( result . getYoyValue ( ) )
. multiply ( new BigDecimal ( 100 ) ) . setScale ( 2 , BigDecimal . ROUND_HALF_UP ) ) ;
} else {
result . setYoyRate ( new BigDecimal ( 0 ) ) ;
}
if ( result . getMomValue ( ) . compareTo ( BigDecimal . ZERO ) ! = 0 ) {
result . setMomRate ( ( result . getCurValue ( ) . subtract ( result . getMomValue ( ) ) )
. divide ( result . getMomValue ( ) )
. multiply ( new BigDecimal ( 100 ) ) . setScale ( 2 , BigDecimal . ROUND_HALF_UP ) ) ;
} else {
result . setMomRate ( new BigDecimal ( 0 ) ) ;
}
}
private List < Map < String , Object > > getStructData ( EnergyQueryVO vo , String systemType ) {
String startTime = vo . getStartTime ( ) . substring ( 0 , 4 ) ;
String endTime = vo . getEndTime ( ) . substring ( 0 , 4 ) ;