From 1571cd0f137ced4345fa8785e166a29dc31b6ad1 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期二, 13 五月 2025 17:42:39 +0800
Subject: [PATCH] 1. 新增动态污染溯源的数据异常判断逻辑 2. 新增动态污染溯源websocket连接功能

---
 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt |  126 ++++++++++++++++++++++-------------------
 1 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
index 63cd9af..52f9cac 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
@@ -1,14 +1,15 @@
 package com.flightfeather.uav.biz.dataanalysis
 
 import com.flightfeather.uav.biz.FactorFilter
-import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig
 import com.flightfeather.uav.domain.entity.BaseRealTimeData
 import com.flightfeather.uav.socket.eunm.FactorType
+import java.time.Duration
 
 /**
  * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,閫傜敤浜庡綋鍓嶆暟鎹笌鐩搁偦鏁版嵁涔嬮棿鏈夊叧鑱斿叧绯荤殑鎯呭喌
  */
-abstract class BaseExceptionContinuous(config: DataAnalysisConfig) : BaseExceptionAnalysis(config) {
+abstract class BaseExceptionContinuous<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) :
+    BaseExceptionAnalysis<V, Y>(config) {
 
     companion object {
         // 璁板綍寮傚父鏁版嵁娈垫椂锛屽垎鍒悜璧峰鍓嶅拰鏈熬鍚庨澶栬褰曠殑鏁版嵁涓暟鍋忕Щ閲�
@@ -20,7 +21,7 @@
         var sIndex = 0
 
         // 璧峰鏁版嵁瀵硅薄
-        var startData :BaseRealTimeData? = null
+        var startData: BaseRealTimeData? = null
 
         // 鏈熬鏁版嵁涓嬫爣
         var eIndex = -1
@@ -38,30 +39,28 @@
             sIndex = eIndex
             startData = data
             exceptionData.clear()
-            exceptionData.add(data)
+//            exceptionData.add(data)
         }
     }
 
     protected val tagMap = mutableMapOf<FactorType, Tag>()
 
-//    // 璧峰鏁版嵁涓嬫爣
-//    protected var sIndex = mutableListOf<Int>()
-//
-//    // 璧峰鏁版嵁瀵硅薄
-//    protected var startData = mutableListOf<BaseRealTimeData?>()
-//
-//    // 鏈熬鏁版嵁涓嬫爣
-//    protected var eIndex = mutableListOf<Int>()
-//
-//    // 寮傚父鏁版嵁娈�
-//    protected var exceptionData = mutableListOf<MutableList<BaseRealTimeData>>()
-
-//    protected var existException = mutableListOf<Boolean>()
-
     // 璧峰鏁版嵁涓庢湯灏炬暟鎹棿闅�
     open var durationCount = 1
+
     // 鏈熬鏁版嵁瀵硅薄
     protected var lastData: BaseRealTimeData? = null
+
+    /**
+     * 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画
+     */
+    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)
+    }
 
     /**
      * 鍒ゆ柇鏄惁婊¤冻寮傚父鏉′欢
@@ -69,24 +68,25 @@
     abstract fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean>
 
     /**
-     * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁椂闀挎槸鍚︽弧瓒虫潯浠�
-     * @param sIndex
-     * @param eIndex
+     * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁釜鏁版槸鍚︽弧瓒虫潯浠�
+     * @param tag 寮傚父鏁版嵁瀵硅薄
      */
-    abstract fun judgeDuration(sIndex: Int, eIndex: Int): Boolean
+    abstract fun judgeExceptionCount(tag: Tag): Boolean
+
+    /**
+     * 寮傚父鏁版嵁鐨勬埅鍙栧垽鏂�
+     * 鏄惁闇�瑕侀檺鍒朵竴缁勫紓甯告暟鎹殑闀垮害
+     * @return 榛樿涓嶉渶瑕佹埅鍙�
+     */
+    open fun needCut(tag: Tag): Boolean {
+        return false
+    }
 
     override fun init() {
         super.init()
         lastData = null
-//        repeat(config.factorCount) {
-//            startData.add(null)
-//            sIndex.add(0)
-//            eIndex.add(-1)
-//            existException.add(false)
-//            exceptionData.add(mutableListOf())
-//        }
         tagMap.clear()
-        config.factorFilter.mainList().forEach {f->
+        config.factorFilter.mainList().forEach { f ->
             tagMap[f] = Tag()
         }
     }
@@ -94,17 +94,17 @@
     override fun onNextData(data: BaseRealTimeData) {
         val isContinue = isContinuous(lastData, data)
         val hasException = judgeException(lastData, data)
-        config.factorFilter.selectedList.forEach {s->
+        config.factorFilter.selectedList.forEach { s ->
             val f = s.main
             tagMap[f]?.let {
                 it.eIndex++
                 // 璧峰鏁版嵁
-                it.endData = lastData
-                if (it.endData == null) {
+                it.endData = data
+                if (it.startData == null) {
                     it.refreshAfterCheckResult(data)
                 }
                 // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇
-                if (!isContinue) {
+                if (!isContinue || needCut(it)) {
                     checkResult(s)
                     // 鏁版嵁涓嶈繛缁椂锛岃褰曞紓甯告儏鍐�
                     if (it.eIndex - it.sIndex >= durationCount) {
@@ -131,43 +131,51 @@
         checkResult()
     }
 
-//    fun refreshAfterCheckResult(i:Int, data: BaseRealTimeData) {
-//        sIndex[i] = eIndex[i]
-//        startData[i] = data
-//        exceptionData[i].clear()
-//        exceptionData[i].add(data)
-//    }
-
     /**
      * 妫�鏌ヨ繛缁紓甯哥粨鏉熸椂锛屾槸鍚︾鍚堝紓甯稿瓨鍌ㄦ潯浠�
      */
     open fun checkResult(factor: FactorFilter.SelectedFactor? = null) {
         val tag = tagMap[factor?.main]
         if (factor != null && tag != null) {
-            if (tag.existException && judgeDuration(tag.sIndex, tag.eIndex - 1)) {
-                tag.startData?.let {
-                    resultList.add(newResult(it, lastData, factor, tag.exceptionData))
-                }
-                tag.existException = false
+            if (tag.existException && judgeExceptionCount(tag)) {
+                onNewException(tag, factor)
+//                tag.startData?.let {
+//                    resultList.add(newResult(it, lastData, factor, tag.exceptionData))
+//                }
+//                tag.existException = false
             }
         } else {
             config.factorFilter.selectedList.forEach { f ->
                 val tag1 = tagMap[f.main] ?: return@forEach
-                if (tag1.existException && judgeDuration(tag1.sIndex, tag1.eIndex - 1)) {
-                    tag1.startData?.let {
-                        resultList.add(newResult(it, lastData, f, tag1.exceptionData))
-                    }
-                    tag1.existException = false
+                if (tag1.existException && judgeExceptionCount(tag1)) {
+                    onNewException(tag1, f)
+//                    tag1.startData?.let {
+//                        resultList.add(newResult(it, lastData, f, tag1.exceptionData))
+//                    }
+//                    tag1.existException = false
                 }
             }
-//            repeat(config.factorCount) { i ->
-//                if (existException[i] && judgeDuration(sIndex[i], eIndex[i])) {
-//                    startData[i]?.let {
-//                        resultList.add(newResult(it, lastData, i, exceptionData[i]))
-//                    }
-//                    existException[i] = false
-//                }
-//            }
         }
     }
+
+    /**
+     * 鏂板涓�鏉″紓甯�
+     */
+    open fun onNewException(tag:Tag, factor: FactorFilter.SelectedFactor) {
+        tag.startData?.let {
+            resultList.add(newResult(it, lastData, factor, tag.exceptionData))
+        }
+        tag.existException = false
+    }
+
+    /**
+     * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋�
+     */
+    abstract fun newResult(
+        start: BaseRealTimeData,
+        end: BaseRealTimeData?,
+        factor: FactorFilter.SelectedFactor,
+        exceptionData: List<BaseRealTimeData>,
+    ): Y
+
 }
\ No newline at end of file

--
Gitblit v1.9.3