feiyu02
2025-07-21 38d72198bfcced01ed9513b978163e5cd1d84625
src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt
@@ -1,18 +1,14 @@
package com.flightfeather.uav.biz.dataanalysis
import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
import com.flightfeather.uav.biz.FactorFilter
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.socket.eunm.FactorType
import java.time.Duration
/**
 * 监测数据异常分析基类
 */
abstract class BaseExceptionAnalysis(config: DataAnalysisConfig) :
    BaseDataAnalysis<BaseRealTimeData, DataAnalysisConfig, ExceptionResult>(config) {
abstract class BaseExceptionAnalysis<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) :
    BaseDataAnalysis<BaseRealTimeData, V, Y>(config) {
    /**
     * 确定异常类型
@@ -20,63 +16,12 @@
    abstract fun getExceptionType(): ExceptionType
    /**
     * 判断相邻数据是否连续
     */
    open fun isContinuous(d1: BaseRealTimeData?, d2: BaseRealTimeData?): Boolean {
        if (d1 == null || d2 == null) return true
        val t1 = d1.dataTime
        val t2 = d2.dataTime
        return Duration.between(t1?.toInstant(), t2?.toInstant()).toMillis() <= (20 * 1000)
    }
    /**
     * 生成一条异常分析结果
     */
    open fun newResult(
        start: BaseRealTimeData, end: BaseRealTimeData?, factorIndex: Int,
        exceptionData: List<BaseRealTimeData>,
    ): ExceptionResult {
        val eType = getExceptionType()
        val factorType = FactorType.getByIndex(factorIndex)
        return ExceptionResult().apply {
            missionCode = config.mission.missionCode
            deviceCode = start.deviceCode
            exception = eType.des
            exceptionType = eType.value
            factorId = factorType?.value
            factorName = factorType?.des
            startTime = DateUtil.instance.dateToString(start.dataTime, DateUtil.DateStyle.HH_MM_SS)
            endTime = DateUtil.instance.dateToString(end?.dataTime, DateUtil.DateStyle.HH_MM_SS) ?: startTime
            startData = start.getByFactorIndex(factorIndex)
            endData = end?.getByFactorIndex(factorIndex) ?: startData
            val s = dataSummary(exceptionData, factorIndex)
            avg = s.first
            min = s.second
            max = s.third
            exceptionData.forEach { dataList.add(it) }
        }
    }
    fun dataSummary(exceptionData: List<BaseRealTimeData?>, factorIndex: Int): Triple<Float, Float, Float> {
        var min = -1f
        var max = -1f
        var total = 0f
        var count = 0
        exceptionData.forEach {
            val value = it?.getByFactorIndex(factorIndex) ?: return@forEach
            if (min == -1f || min > value) {
                min = value
            }
            if (max == -1f || max < value) {
                max = value
            }
            total += value
            count++
        }
        val avg = if (count == 0) 0f else total / count
        return Triple(avg, min, max)
    }
//    abstract fun newResult(
//        start: BaseRealTimeData,
//        end: BaseRealTimeData?,
//        factor: FactorFilter.SelectedFactor,
//        exceptionData: List<BaseRealTimeData>,
//    ): Y
}