From 594de76ed51fd49fb79b912212bb0052a63e7671 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期四, 09 四月 2026 16:10:45 +0800
Subject: [PATCH] 2026.4.9

---
 src/main/kotlin/com/flightfeather/uav/domain/repository/SourceTraceRep.kt |  106 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 84 insertions(+), 22 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/SourceTraceRep.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/SourceTraceRep.kt
index b4f945a..d5c2e0a 100644
--- a/src/main/kotlin/com/flightfeather/uav/domain/repository/SourceTraceRep.kt
+++ b/src/main/kotlin/com/flightfeather/uav/domain/repository/SourceTraceRep.kt
@@ -6,10 +6,14 @@
 import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
 import com.flightfeather.uav.biz.sourcetrace.model.PollutedSummary
 import com.flightfeather.uav.common.utils.GsonUtils
+import com.flightfeather.uav.domain.entity.Mission
 import com.flightfeather.uav.domain.entity.SourceTraceMsg
+import com.flightfeather.uav.domain.entity.SourceTraceMsgBlob
+import com.flightfeather.uav.domain.mapper.SourceTraceMsgBlobMapper
 import com.flightfeather.uav.domain.mapper.SourceTraceMsgMapper
 import com.flightfeather.uav.socket.sender.MsgType
 import org.springframework.stereotype.Repository
+import org.springframework.transaction.annotation.Transactional
 import tk.mybatis.mapper.entity.Example
 import java.util.*
 
@@ -19,11 +23,22 @@
  * @author feiyu02
  */
 @Repository
-class SourceTraceRep(private val sourceTraceMsgMapper: SourceTraceMsgMapper) {
+class SourceTraceRep(
+    private val sourceTraceMsgMapper: SourceTraceMsgMapper,
+    private val sourceTraceMsgBlobMapper: SourceTraceMsgBlobMapper,
+) {
+
+    private fun insertBlob(stm: SourceTraceMsg, json: String) {
+        sourceTraceMsgBlobMapper.insert(SourceTraceMsgBlob().apply {
+            msgId = stm.id
+            content = json
+        })
+    }
 
     /**
      * 鎻掑叆婧簮淇℃伅鍜屾彁閱掍俊鎭�
      */
+    @Transactional
     fun insert(msgType: MsgType, obj: PollutedClue): Int {
         val stm = SourceTraceMsg().apply {
             deviceCode = obj.deviceCode
@@ -32,11 +47,12 @@
             startTime = obj.pollutedData?.startTime
             endTime = obj.pollutedData?.endTime
             this.msgType = msgType.value
-            content = GsonUtils.gson.toJson(obj)
             createTime = Date()
         }
         return if (fetchOneExist(stm) == null) {
-            sourceTraceMsgMapper.insert(stm)
+            val c = sourceTraceMsgMapper.insert(stm)
+            insertBlob(stm, GsonUtils.gson.toJson(obj))
+            c
         } else {
             0
         }
@@ -53,17 +69,19 @@
     /**
      * 鎻掑叆绾跨储淇℃伅
      */
+    @Transactional
     fun insert(res: AnalysisResult): Int {
         val stm = SourceTraceMsg().apply {
             deviceCode = res.deviceCode
             startTime = res.time
             endTime = res.time
             this.msgType = MsgType.AnaResult.value
-            content = GsonUtils.gson.toJson(res)
             createTime = Date()
         }
         return if (fetchOneExist(stm) == null) {
-            sourceTraceMsgMapper.insert(stm)
+            val c = sourceTraceMsgMapper.insert(stm)
+            insertBlob(stm, GsonUtils.gson.toJson(res))
+            c
         } else {
             0
         }
@@ -81,26 +99,70 @@
         return if (res.isEmpty()) null else res[0]
     }
 
-    fun fetchList(deviceCode: String, startTime: Date, endTime: Date): List<BaseExceptionResult?> {
-        return sourceTraceMsgMapper.selectByExample(Example(SourceTraceMsg::class.java).apply {
-            createCriteria().andEqualTo("deviceCode", deviceCode)
-                .andGreaterThanOrEqualTo("startTime", startTime)
-                .andLessThanOrEqualTo("endTime", endTime)
-            orderBy("id").desc()
-        }).map { stm ->
-            when (stm?.msgType) {
-                MsgType.PolClue.value,
-                MsgType.DataChange.value,
-                    -> {
-                    GsonUtils.gson.fromJson(stm.content, PollutedClue::class.java)
-                }
+    val stMsgCache = mutableMapOf<String, List<BaseExceptionResult?>>()
+    fun fetchList(
+        deviceCode: String,
+        startTime: Date,
+        endTime: Date,
+        msgType: MsgType? = null,
+        minPer: Double? = 0.5,
+    ): List<BaseExceptionResult?> {
+        var stMsgList = listOf<BaseExceptionResult?>()
+        val key = "${deviceCode}_${startTime.time}_${endTime.time}_${msgType?.value}"
+        if (stMsgCache.containsKey(key)) {
+            stMsgList = stMsgCache[key]!!
+        }
+        if (stMsgList.isEmpty()) {
+            var res = sourceTraceMsgBlobMapper.selectWithBlob(deviceCode, startTime, endTime)
+            if (msgType !== null) {
+                res = res.filter { it?.msgType == msgType.value }
+            }
 
-                MsgType.AnaResult.value -> {
-                    GsonUtils.gson.fromJson(stm.content, AnalysisResult::class.java)
-                }
+            stMsgList = res.map { stm ->
+                when (stm?.msgType) {
+                    MsgType.PolClue.value,
+                    MsgType.DataChange.value,
+                        -> {
+                        GsonUtils.gson.fromJson(stm.blobContent, PollutedClue::class.java)
+                    }
 
-                else -> null
+                    MsgType.AnaResult.value -> {
+                        GsonUtils.gson.fromJson(stm.blobContent, AnalysisResult::class.java)
+                    }
+
+                    else -> null
+                }
+            }
+            // Fixme 2026.1.21 婧簮璁板綍鐨勭紦瀛橀�昏緫鏆傜己澶憋紝姝ゅ澶勭悊涓嶆伆褰�
+//            stMsgCache[key] = stMsgList
+        }
+        // 绛涢�夊嚭寮傚父鏁版嵁PollutedClue涓紓甯哥櫨鍒嗘瘮澶т簬minPer鐨�
+        return stMsgList.filter {
+            if (it is PollutedClue) {
+                var valid = false
+                (it as PollutedClue?)?.pollutedData?.statisticMap?.entries?.forEach {sta->
+                    if (!valid) valid = (sta.value.avgPer?:.0) > minPer!!
+                }
+                valid
+            } else {
+                true
             }
         }
     }
+
+    @Transactional
+    fun delete(mission: Mission): Int {
+        val idList = sourceTraceMsgMapper.selectByExample(Example(SourceTraceMsg::class.java).apply {
+            createCriteria().andEqualTo("deviceCode", mission.deviceCode)
+                .andGreaterThanOrEqualTo("startTime", mission.startTime)
+                .andLessThanOrEqualTo("endTime", mission.endTime)
+        }).map { it?.id }
+        if (idList.isEmpty()) return 0
+        sourceTraceMsgMapper.deleteByExample(Example(SourceTraceMsg::class.java).apply {
+            createCriteria().andIn("id", idList)
+        })
+        return sourceTraceMsgBlobMapper.deleteByExample(Example(SourceTraceMsgBlob::class.java).apply {
+            createCriteria().andIn("msgId", idList)
+        })
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3