feiyu02
2025-07-10 c5f380b69707a9a09fe988a2f4bd98e142bf64ae
src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
@@ -1,55 +1,45 @@
package com.flightfeather.uav.biz.dataanalysis
import com.flightfeather.uav.biz.FactorFilter
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType
import com.flightfeather.uav.socket.eunm.FactorType
import java.time.Duration
/**
 * 连续类型的异常分析基类,适用于当前数据与相邻数据之间有关联关系的情况
 */
abstract class BaseExceptionContinuous<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) :
    BaseExceptionAnalysis<V, Y>(config) {
abstract class BaseExceptionContinuous<T : ExceptionTag, V : BaseAnalysisConfig, Y : BaseExceptionResult>(
    config: V, private val tagClz: Class<T>
) : BaseExceptionAnalysis<V, Y>(config) {
    companion object {
        // 记录异常数据段时,分别向起始前和末尾后额外记录的数据个数偏移量
        private const val OFFSET = 10
    }
    inner class Tag {
        // 起始数据下标
        var sIndex = 0
        // 起始数据对象
        var startData: BaseRealTimeData? = null
        // 末尾数据下标
        var eIndex = -1
        // 末尾数据对象
        var endData: BaseRealTimeData? = null
        // 异常数据段
        var exceptionData = mutableListOf<BaseRealTimeData>()
        // 是否存在异常
        var existException = false
        fun refreshAfterCheckResult(data: BaseRealTimeData) {
            sIndex = eIndex
            startData = data
            exceptionData.clear()
//            exceptionData.add(data)
        }
    }
    protected val tagMap = mutableMapOf<FactorType, Tag>()
    protected val tagMap = mutableMapOf<FactorType, T>()
    // 起始数据与末尾数据间隔
    open var durationCount = 1
    // 末尾数据对象
    protected var lastData: BaseRealTimeData? = null
    /**
     * 后置判断:当相邻数据时间不连续时,或者满足自定义条件时,对之前已有的异常进行记录
     */
    open fun afterExcCheck(isContinue: Boolean, tag: T, hasException: Boolean?): Boolean {
        return !isContinue || needCut(tag, hasException)
    }
    /**
     * 立即判断:当出现异常时,缓存异常数据的同时,立即对已有异常进行判断是否满足异常结果要求
     */
    open fun immeExcCheck(tag: T, factorType: FactorType): Boolean {
        return false
    }
    /**
     * 判断相邻数据是否连续
@@ -63,7 +53,17 @@
    }
    /**
     * 判断是否满足异常条件
     * 判断数据量级在异常判断的范围内
     * 默认所有量级都在异常判断的范围内
     */
    open fun judgeDataScale(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
        val res = mutableMapOf<FactorType, Boolean>()
        config.factorFilter.mainList().forEach { f -> res[f] = true }
        return res
    }
    /**
     * 判断前后数据是否满足异常条件
     */
    abstract fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean>
@@ -71,15 +71,28 @@
     * 判断异常出现的连续个数是否满足条件
     * @param tag 异常数据对象
     */
    abstract fun judgeExceptionCount(tag: Tag): Boolean
    abstract fun judgeExceptionCount(tag: T, factorType: FactorType?): Boolean
    /**
     * 判断监测因子是否出现异常
     */
    open fun judge(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
        val jds = judgeDataScale(p, n)
        val jex = judgeException(p, n)
        val res = mutableMapOf<FactorType, Boolean>()
        jds.forEach { (t, u) ->
            res[t] = u && jex[t] ?: false
        }
        return res
    }
    /**
     * 异常数据的截取判断
     * 是否需要限制一组异常数据的长度
     * @return 默认不需要截取
     * @return
     */
    open fun needCut(tag: Tag): Boolean {
        return false
    open fun needCut(tag: T, hasException: Boolean?): Boolean {
        // 默认判断条件为 当异常不再重复出现时,形成异常结果
        return tag.exceptionExisted && hasException == false
    }
    override fun init() {
@@ -87,96 +100,114 @@
        lastData = null
        tagMap.clear()
        config.factorFilter.mainList().forEach { f ->
            tagMap[f] = Tag()
            tagMap[f] = tagClz.newInstance()
        }
    }
    override fun onNextData(data: BaseRealTimeData) {
        val isContinue = isContinuous(lastData, data)
        val hasException = judgeException(lastData, data)
        val hasException = judge(lastData, data)
        config.factorFilter.selectedList.forEach { s ->
            val f = s.main
            tagMap[f]?.let {
                it.addHistoryData(data)
                it.eIndex++
                // 起始数据
                it.endData = data
                if (it.startData == null) {
                    it.refreshAfterCheckResult(data)
                    it.refreshWithNextException(data)
                }
                // 判断相邻数据是否连续并且是否满足异常判断
                if (!isContinue || needCut(it)) {
                    // 数据不连续时,记录异常情况
                    recordException(s, it, data)
//                    checkResult(s)
//                    if (it.eIndex - it.sIndex >= durationCount) {
//                        it.refreshAfterCheckResult(data)
//                    }
                } else {
                    if (hasException[f] == true) {
                        it.existException = true
                        it.exceptionData.add(data)
                    } else {
                        // 异常不再重复出现时,记录异常情况
                // 对于异常的生成分别执行后置判断、和立即判断
                // 1. 后置判断:当相邻数据时间不连续时,或者满足自定义条件时,对之前已有的异常进行记录,形成异常结果
//                if (afterExcCheck(isContinue, it, hasException[f])) {
//                    // 数据不连续时或者满足主动截断条件时,记录异常情况
//                    recordException(s, it, data)
//                }
                // 2. 立即判断:当出现异常时,缓存异常数据的同时,立即对已有异常进行判断是否满足异常结果要求
                if (hasException[f] == true) {
//                    afterExcCheck(isContinue, it, hasException[f])
                    needCut(it, hasException[f])
                    // 有异常出现时,记录异常数据
                    it.addExceptionData(data)
                    // 当立即判断通过时,形成异常结果
                    if (immeExcCheck(it, f)) {
                        recordException(s, it, data)
//                        checkResult(s)
//                        if (it.eIndex - it.sIndex >= durationCount) {
//                            it.refreshAfterCheckResult(data)
//                        }
                    }
                }
                // 3. 数据正常,无任何异常时d
                // TODO("2025.6.3:其他子类的此处刷新逻辑待完成“)
//                else {
//                    it.refreshWithNextException(data)
//                }
            }
        }
        lastData = data
    }
    override fun onDone() {
        checkResult()
        checkResult(exceptionStatus = ExceptionStatusType.Ended)
    }
    fun recordException(factor: FactorFilter.SelectedFactor, tag: Tag, data: BaseRealTimeData) {
        checkResult(factor)
        if (tag.eIndex - tag.sIndex >= durationCount) {
            tag.refreshAfterCheckResult(data)
        }
    /**
     * 异常结束,记录异常
     * 判断已有的异常数据是否满足异常条件,满足则记录,不满足则略过
     */
    fun recordException(factor: FactorFilter.SelectedFactor, tag: T, data: BaseRealTimeData) {
        checkResult(factor, ExceptionStatusType.Ended)
        tag.refreshWithNextException(data)
    }
    /**
     * 检查连续异常结束时,是否符合异常存储条件
     */
    open fun checkResult(factor: FactorFilter.SelectedFactor? = null) {
    open fun checkResult(
        factor: FactorFilter.SelectedFactor? = null,
        exceptionStatus: ExceptionStatusType = ExceptionStatusType.InProgress
    ) {
        val tag = tagMap[factor?.main]
        if (factor != null && tag != null) {
            if (tag.existException && judgeExceptionCount(tag)) {
                onNewException(tag, factor)
            if (tag.exceptionExisted && judgeExceptionCount(tag, factor.main)) {
                onNewException(tag, factor, exceptionStatus)
            }
        } else {
            config.factorFilter.selectedList.forEach { f ->
                val tag1 = tagMap[f.main] ?: return@forEach
                if (tag1.existException && judgeExceptionCount(tag1)) {
                    onNewException(tag1, f)
                if (tag1.exceptionExisted && judgeExceptionCount(tag1, f.main)) {
                    onNewException(tag1, f, exceptionStatus)
                }
            }
        }
    }
    /**
     * 新增一条异常
     * 新增或更新一条异常
     */
    open fun onNewException(tag:Tag, factor: FactorFilter.SelectedFactor) {
        tag.startData?.let {
            resultList.add(newResult(it, lastData, factor, tag.exceptionData))
    open fun onNewException(tag: T, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) {
        if (tag.startData == null) return
//        val ex = newResult(tag.startData!!, tag.endData, factor, tag.exceptionData)
        val ex = newResult(tag, factor)
            .apply { status = exceptionStatus.value }
        // 异常已创建时,更新异常信息
        if (tag.exceptionCreated) {
            // 将最新的异常的guid赋值给ex
            val lastEx = tag.exceptionResult.last()
            ex.guid = lastEx.guid
            tag.exceptionResult.removeLast()
            tag.exceptionResult.add(ex)
        }
        tag.existException = false
        // 异常未创建时,新建异常信息
        else {
            tag.exceptionResult.add(ex)
//            resultList.add(ex)
            tag.exceptionCreated = true
        }
    }
    /**
     * 生成一条异常分析结果
     */
    abstract fun newResult(
        start: BaseRealTimeData,
        end: BaseRealTimeData?,
        factor: FactorFilter.SelectedFactor,
        exceptionData: List<BaseRealTimeData>,
    ): Y
    abstract fun newResult(tag:T, factor: FactorFilter.SelectedFactor): Y
}