@ -1,9 +1,7 @@
package com.dongjian.dashboard.back.service.common ;
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
import java.math.BigDecimal ;
import java.sql.* ;
import java.time.Instant ;
import java.time.LocalDate ;
import java.time.ZoneId ;
@ -142,6 +140,23 @@ public class CommonOpt {
return dbUrl . replaceAll ( regex , "$1" + auroraHost + "$3" ) ;
}
public String extractValue ( ObjectMapper mapper , Integer typeId , String rawData ) {
if ( Constants . DEVICE_TYPE_TEMPERATURE_HUMIDITY . contains ( typeId ) ) {
List < String > values = extractAllValues ( mapper , rawData ) ;
List < String > result = new ArrayList < > ( ) ;
for ( int i = 0 ; i < values . size ( ) ; i + + ) {
if ( 0 = = i ) {
result . add ( values . get ( i ) ) ;
} else if ( 1 = = i ) {
result . add ( values . get ( i ) ) ;
}
}
return StringUtils . join ( result , "," ) ;
} else {
return extractFirstValue ( mapper , rawData ) ;
}
}
public String extractFirstValue ( ObjectMapper mapper , String rawData ) {
if ( StringUtils . isBlank ( rawData ) ) {
return "" ;
@ -158,6 +173,33 @@ public class CommonOpt {
return "" ;
}
public List < String > extractAllValues ( ObjectMapper mapper , String rawData ) {
List < String > result = new ArrayList < > ( ) ;
if ( StringUtils . isBlank ( rawData ) ) {
return result ;
}
try {
JsonNode node = mapper . readTree ( rawData ) ;
if ( ! node . isObject ( ) ) {
return result ;
}
Iterator < Map . Entry < String , JsonNode > > fields = node . fields ( ) ;
while ( fields . hasNext ( ) ) {
JsonNode valueNode = fields . next ( ) . getValue ( ) ;
result . add ( valueNode . isValueNode ( ) ? valueNode . asText ( ) : valueNode . toString ( ) ) ;
}
} catch ( Exception e ) {
logger . error ( "Failed to parse multi rawData JSON: {}" , rawData , e ) ;
}
return result ;
}
public List < Long > getBindBuildingIdList ( Long userId ) {
Integer buildingManager = basicUserMapperExt . checkBuildingManager ( userId ) ;
if ( buildingManager > 0 ) {
@ -188,8 +230,11 @@ public class CommonOpt {
return dateList ;
}
public LineData getLineData ( Long companyId , LineDataSearchParams lineDataSearchParams ) {
public List < LineData > getLineData ( Long companyId , LineDataSearchParams lineDataSearchParams , int deviceType ) {
List < LineData > lineDataList = new ArrayList < > ( ) ;
for ( String attrCode : lineDataSearchParams . getAttrCodeList ( ) ) {
LineData lineData = new LineData ( ) ;
lineData . setAttrCode ( attrCode ) ;
try {
Map < String , Object > apikeyParamMap = new HashMap < > ( ) ;
apikeyParamMap . put ( "companyId" , companyId ) ;
@ -197,7 +242,7 @@ public class CommonOpt {
if ( null = = apikeyInfo ) {
logger . error ( "Failed to get AuroraInfo for companyId: {}" , companyId ) ;
return lineData ;
lineDataList . add ( lineData ) ;
}
if ( StringUtils . isNotBlank ( apikeyInfo . getAuroraUrl ( ) ) ) {
@ -219,18 +264,45 @@ public class CommonOpt {
List < String > dateList = getPreDay ( 1 ) ;
for ( String date : dateList ) {
String baseSql = "SELECT rawData, receive_ts FROM rawData_" + date + " WHERE deviceId = ? order by receive_ts " ;
String sql = baseSql ;
//获取昨天的值,这里只针对累积设备
Double lastDayValue = null ;
if ( deviceType = = 2 ) {
lastDayValue = getLastDayValue ( conn , date , lineDataSearchParams . getDeviceId ( ) ) ;
}
// 提取年、月、日
DateTimeFormatter formatter = DateTimeFormatter . ofPattern ( "yyyy_MM_dd" ) ;
LocalDate currentDate = LocalDate . parse ( date , formatter ) ;
int year = currentDate . getYear ( ) ;
int month = currentDate . getMonthValue ( ) ;
int day = currentDate . getDayOfMonth ( ) ;
String sql = "" ;
if ( deviceType = = 2 ) {
sql = "SELECT upload_value, upload_at FROM dashboard_record_accumulate " +
"WHERE device_id = ? AND attr_code = ? AND date_year = ? AND date_month = ? AND date_day = ? order by id " ;
} else if ( deviceType = = 3 ) {
sql = "SELECT upload_value, upload_at FROM dashboard_record_measure " +
"WHERE device_id = ? AND attr_code = ? AND date_year = ? AND date_month = ? AND date_day = ? order by id " ;
}
logger . info ( "getLineData sql: {}" , sql ) ;
try ( PreparedStatement preparedStatement = conn . prepareStatement ( sql ) ) {
preparedStatement . setString ( 1 , lineDataSearchParams . getDeviceId ( ) ) ;
preparedStatement . setString ( 2 , attrCode ) ;
preparedStatement . setInt ( 3 , year ) ; // 设置年份
preparedStatement . setInt ( 4 , month ) ; // 设置月份
preparedStatement . setInt ( 5 , day ) ; // 设置日期
try ( ResultSet result = preparedStatement . executeQuery ( ) ) {
if ( result . next ( ) ) {
if ( deviceType = = 2 ) {
processResult ( result , lineData , lastDayValue ) ;
} else if ( deviceType = = 3 ) {
processResult ( result , lineData ) ;
}
}
}
}
}
} catch ( Exception e ) {
logger . error ( "getLineData processing aurora error" , e ) ;
}
@ -239,7 +311,46 @@ public class CommonOpt {
} catch ( Exception e ) {
logger . error ( "getLineData error" , e ) ;
}
return lineData ;
lineDataList . add ( lineData ) ;
}
return lineDataList ;
}
private Double getLastDayValue ( Connection conn , String date , String deviceId ) {
DateTimeFormatter formatter = DateTimeFormatter . ofPattern ( "yyyy_MM_dd" ) ;
// 解析日期字符串为 LocalDate 对象
LocalDate previousDate = LocalDate . parse ( date , formatter ) ;
// 获取前一天的日期
LocalDate previousDay = previousDate . minusDays ( 1 ) ;
// 获取年、月、日
int year = previousDay . getYear ( ) ;
int month = previousDay . getMonthValue ( ) ;
int day = previousDay . getDayOfMonth ( ) ;
String sql = "SELECT upload_value FROM dashboard_realtime_accumulate_day " +
"WHERE device_id = ? AND date_year = ? AND date_month = ? AND date_day = ?" ;
logger . info ( "getUploadValue sql: {}" , sql ) ;
try ( PreparedStatement preparedStatement = conn . prepareStatement ( sql ) ) {
preparedStatement . setString ( 1 , deviceId ) ; // 设置设备ID
preparedStatement . setInt ( 2 , year ) ; // 设置年份
preparedStatement . setInt ( 3 , month ) ; // 设置月份
preparedStatement . setInt ( 4 , day ) ; // 设置日期
try ( ResultSet result = preparedStatement . executeQuery ( ) ) {
if ( result . next ( ) ) {
String uploadValue = result . getString ( "upload_value" ) ;
logger . info ( "Found upload_value: {}" , uploadValue ) ;
return new BigDecimal ( uploadValue ) . doubleValue ( ) ;
} else {
logger . warn ( "No data found for deviceId: {} on {}/{}/{}" , deviceId , year , month , day ) ;
}
}
} catch ( SQLException e ) {
logger . error ( "Error getLastDayValue query: " , e ) ;
}
return null ;
}
private void processResult ( ResultSet result , LineData lineData ) {
@ -255,8 +366,8 @@ public class CommonOpt {
// 遍历查询结果
do {
// 获取 receive_ts 和 rawData
long receiveTs = result . getLong ( "receive_ts " ) ;
String rawData = result . getString ( "rawData " ) ;
long receiveTs = result . getLong ( "upload_at " ) ;
String value = result . getString ( "upload_value " ) ;
// 如果 receiveTs 为 0(表示无效时间戳),跳过当前行
if ( receiveTs = = 0 ) {
@ -272,7 +383,7 @@ public class CommonOpt {
xDataList . add ( formattedDate ) ;
// 将 rawData解析 添加到 yData
String value = extractFirstValue ( mapper , rawData ) ;
// String value = extractFirstValue(mapper, rawData);
yDataList . add ( StringUtils . isBlank ( value ) ? "0" : value ) ;
} while ( result . next ( ) ) ;
@ -285,4 +396,64 @@ public class CommonOpt {
}
}
private void processResult ( ResultSet result , LineData lineData , Double lastDayValue ) {
try {
// 用于存储 xData 和 yData
List < Object > xDataList = new ArrayList < > ( ) ;
List < Object > yDataList = new ArrayList < > ( ) ;
// 使用 DateTimeFormatter 来格式化时间
DateTimeFormatter formatter = DateTimeFormatter . ofPattern ( "yyyy-MM-dd HH:mm:ss" ) ;
ObjectMapper mapper = new ObjectMapper ( ) ;
// 用于存储每个小时最后一条数据(仅在 deviceType = 2 时使用)
Map < String , Double > lastHourData = new LinkedHashMap < > ( ) ; // 按插入顺序保存数据
// 遍历查询结果
do {
// 获取 receive_ts 和 rawData
long receiveTs = result . getLong ( "upload_at" ) ;
String value = result . getString ( "upload_value" ) ;
// 如果 receiveTs 为 0(表示无效时间戳),跳过当前行
if ( receiveTs = = 0 ) {
continue ; // 跳过当前循环的剩余部分,继续处理下一行
}
// 将 long 时间戳转换为 LocalDateTime(日本时区)
Instant instant = Instant . ofEpochMilli ( receiveTs ) ;
String formattedDate = instant . atZone ( ZoneId . of ( "Asia/Tokyo" ) )
. toLocalDateTime ( )
. format ( formatter ) ;
// 将 rawData解析 添加到 yData
// String value = extractFirstValue(mapper, rawData);
double todayValue = StringUtils . isBlank ( value ) ? 0 . 0 : new BigDecimal ( value ) . doubleValue ( ) ;
//计算差值
double yValue = todayValue ; //默认今天值
if ( null ! = lastDayValue & & yValue > = lastDayValue ) {
yValue = todayValue - lastDayValue ;
}
// 按小时分组,每个小时只保存最后一条数据
String hourKey = formattedDate . substring ( 0 , 13 ) + ":00:00" ;
lastHourData . put ( hourKey , yValue ) ;
} while ( result . next ( ) ) ;
//只取每小时的最后一条数据
for ( Map . Entry < String , Double > entry : lastHourData . entrySet ( ) ) {
xDataList . add ( entry . getKey ( ) ) ; // 添加每小时的时间
yDataList . add ( entry . getValue ( ) ) ; // 添加每小时最后一条数据的值
}
// 将处理后的数据加入到 lineData 中
lineData . getXData ( ) . addAll ( xDataList ) ;
lineData . getYData ( ) . addAll ( yDataList ) ;
} catch ( Exception e ) {
logger . error ( "Error processing result set" , e ) ;
}
}
}