From 29383149f7040d89ae00ad48dc48bbcf46587946 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期一, 01 九月 2025 17:32:53 +0800
Subject: [PATCH] 2025.9.1 1. 新增走航任务统计功能(待完成)

---
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt |  160 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 140 insertions(+), 20 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
index 3982b5c..9826661 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
@@ -1,32 +1,33 @@
 package com.flightfeather.uav.lightshare.service.impl
 
 import com.flightfeather.uav.biz.FactorFilter
-import com.flightfeather.uav.biz.dataanalysis.BaseExceptionResult
 import com.flightfeather.uav.biz.dataanalysis.ExceptionAnalysisController
 import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
+import com.flightfeather.uav.biz.report.MissionInventory
+import com.flightfeather.uav.biz.report.MissionRiskArea
 import com.flightfeather.uav.biz.report.MissionSummary
-import com.flightfeather.uav.biz.sourcetrace.model.BasePollutedMsg
 import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
 import com.flightfeather.uav.common.exception.BizException
 import com.flightfeather.uav.common.location.LocationRoadNearby
 import com.flightfeather.uav.common.utils.GsonUtils
+import com.flightfeather.uav.domain.entity.BaseRealTimeData
 import com.flightfeather.uav.domain.entity.Mission
+import com.flightfeather.uav.domain.entity.SceneInfo
 import com.flightfeather.uav.domain.mapper.MissionMapper
-import com.flightfeather.uav.domain.repository.MissionRep
-import com.flightfeather.uav.domain.repository.RealTimeDataRep
-import com.flightfeather.uav.domain.repository.SegmentInfoRep
-import com.flightfeather.uav.domain.repository.SourceTraceRep
+import com.flightfeather.uav.domain.repository.*
 import com.flightfeather.uav.lightshare.bean.AreaVo
+import com.flightfeather.uav.lightshare.eunm.SceneType
 import com.flightfeather.uav.lightshare.service.DataAnalysisService
 import com.flightfeather.uav.socket.eunm.FactorType
+import com.flightfeather.uav.socket.sender.MsgType
 import org.springframework.stereotype.Service
 import tk.mybatis.mapper.entity.Example
-import java.time.LocalDateTime
-import java.time.ZoneId
 import java.util.*
 
 /**
- *
+ * 鏁版嵁鍒嗘瀽鏈嶅姟鎺ュ彛瀹炵幇绫�
+ * 鎻愪緵璧拌埅浠诲姟鏁版嵁鐨勭粺璁″垎鏋愩�佹薄鏌撴函婧愩�佷换鍔℃竻鍗曞強璇︽儏鐢熸垚绛夋牳蹇冧笟鍔″姛鑳�
+ * 鏁村悎澶氭暟鎹簮瀹屾垚鏁版嵁鑱氬悎涓庡垎鏋愶紝涓哄墠绔彁渚涙爣鍑嗗寲鐨勭粺璁$粨鏋�
  * @date 2025/5/8
  * @author feiyu02
  */
@@ -37,9 +38,18 @@
     private val realTimeDataRep: RealTimeDataRep,
     private val locationRoadNearby: LocationRoadNearby,
     private val segmentInfoRep: SegmentInfoRep,
-    private val sourceTraceRep: SourceTraceRep
+    private val sourceTraceRep: SourceTraceRep,
+    private val sceneInfoRep: SceneInfoRep
 ) : DataAnalysisService {
 
+    /**
+     * 姹℃煋婧簮鍒嗘瀽
+     * 瀵规寚瀹氳蛋鑸换鍔¤繘琛屽鍥犲瓙姹℃煋鏁版嵁鍒嗘瀽锛岃瘑鍒紓甯告暟鎹偣鍜屾綔鍦ㄦ薄鏌撴簮
+     * @param missionCode 璧拌埅浠诲姟缂栫爜锛堜富閿級
+     * @return 寮傚父缁撴灉鍒楄〃锛屽寘鍚紓甯哥被鍨嬨�佷綅缃�佹祿搴﹀�肩瓑璇︾粏淇℃伅
+     * @throws BizException 褰撹蛋鑸换鍔′笉瀛樺湪鏃舵姏鍑�
+     * @see ExceptionAnalysisController 寮傚父鍒嗘瀽鎺у埗鍣紝澶勭悊鍏蜂綋鐨勬暟鎹垎鏋愰�昏緫
+     */
     override fun pollutionTrace(missionCode: String): List<ExceptionResult> {
         val mission = missionRep.findOne(missionCode) ?: throw BizException("璧拌埅浠诲姟涓嶅瓨鍦�")
 
@@ -60,6 +70,13 @@
         )
     }
 
+    /**
+     * 鑾峰彇鍘嗗彶姹℃煋婧簮缁撴灉
+     * 鏌ヨ鎸囧畾浠诲姟鐨勫巻鍙叉薄鏌撴函婧愮粨鏋滃苟搴忓垪鍖栦负JSON瀛楃涓�
+     * @param missionCode 璧拌埅浠诲姟缂栫爜
+     * @return 鍘嗗彶姹℃煋婧簮缁撴灉鐨凧SON瀛楃涓诧紝鍏蜂綋鏍煎紡鐢眘ourceTraceRep瀹炵幇鍐冲畾
+     * @throws BizException 褰撹蛋鑸换鍔′笉瀛樺湪鏃舵姏鍑�
+     */
     override fun fetchHistory(missionCode: String): String {
         val mission = missionRep.findOne(missionCode) ?: throw BizException("璧拌埅浠诲姟涓嶅瓨鍦�")
 
@@ -67,21 +84,124 @@
         return GsonUtils.gson.toJson(res)
     }
 
-    override fun missionSummary(startTime: Date, endTime: Date, areaVo: AreaVo): MissionSummary.Summary {
+    /**
+     * 鐢熸垚璧拌埅浠诲姟姹囨�荤粺璁�
+     * 鎸夋椂闂磋寖鍥村拰琛屾斂鍖哄垝缁熻璧拌埅浠诲姟鐨勫叧閿寚鏍囷紙浠诲姟鏁伴噺銆佸紓甯哥巼銆佸钩鍧囬噷绋嬬瓑锛�
+     * @param startTime 缁熻璧峰鏃堕棿锛堝寘鍚級
+     * @param endTime 缁熻缁撴潫鏃堕棿锛堝寘鍚級
+     * @param areaVo 鍖哄煙鍙傛暟锛屽寘鍚渷銆佸競銆佸尯涓夌骇琛屾斂鍖哄垝缂栫爜
+     * @return 姹囨�荤粺璁″璞★紝鍖呭惈浠诲姟鎬绘暟銆佸紓甯哥偣鏁伴噺銆佸钩鍧囬噷绋嬬瓑鏍稿績鎸囨爣
+     * @see MissionSummary 姹囨�荤粺璁″鐞嗗櫒锛屽皝瑁呭叿浣撶殑缁熻閫昏緫瀹炵幇
+     */
+    override fun generateMissionSummary(startTime: Date, endTime: Date, areaVo: AreaVo): MissionSummary.Summary {
         val clues = mutableListOf<PollutedClue?>()
-        val missions = missionMapper.selectByExample(Example(Mission::class.java).apply {
-            createCriteria().andBetween("startTime", startTime, endTime)
-                .andEqualTo("provinceCode", areaVo.provinceCode)
-                .andEqualTo("cityCode", areaVo.cityCode)
-                .andEqualTo("districtCode", areaVo.districtCode)
-                .andIsNotNull("kilometres")
-                .andNotEqualTo("kilometres", 0)
-        }).onEach {
+        val missions = missionRep.findByAreaAndTime(areaVo, startTime, endTime).onEach {
             it ?: return@onEach
-            val clue = sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime).filterIsInstance<PollutedClue?>()
+            val clue = sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>
             clues.addAll(clue)
         }
         val summary = MissionSummary().execute(startTime, endTime, missions, clues)
         return summary
     }
+
+    /**
+     * 鐢熸垚璧拌埅浠诲姟娓呭崟锛堟寜鏃堕棿鍜屽尯鍩熺瓫閫夛級
+     * 鏍规嵁鏃堕棿鑼冨洿鍜岃鏀垮尯鍒掓煡璇㈣蛋鑸换鍔★紝骞跺叧鑱旀薄鏌撶嚎绱㈡暟鎹敓鎴愪换鍔″垪琛�
+     * @param startTime 鏌ヨ璧峰鏃堕棿锛堝寘鍚級
+     * @param endTime 鏌ヨ缁撴潫鏃堕棿锛堝寘鍚級
+     * @param areaVo 鍖哄煙鍙傛暟锛屽寘鍚渷銆佸競銆佸尯缂栫爜
+     * @return 璧拌埅浠诲姟淇℃伅鍒楄〃锛屾瘡涓厓绱犲寘鍚换鍔″熀鏈俊鎭拰鍏宠仈鐨勬薄鏌撶嚎绱�
+     * @see MissionRep.findByAreaAndTime 鍖哄煙鏃堕棿绛涢�夋暟鎹簮
+     * @see generateMissionList 閲嶈浇鏂规硶锛屽鐞嗗凡鍏宠仈鐨勬暟鎹
+     */
+    override fun generateMissionList(startTime: Date, endTime: Date, areaVo: AreaVo): List<MissionInventory.MissionInfo> {
+        val missionClues = missionRep.findByAreaAndTime(areaVo, startTime, endTime).filterNotNull().map {
+            it to sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>
+        }
+        return generateMissionList(missionClues)
+    }
+
+    /**
+     * 鐢熸垚璧拌埅浠诲姟娓呭崟锛堢洿鎺ュ鐞嗕换鍔℃暟鎹級
+     * 鎺ユ敹宸插叧鑱旂殑浠诲姟-姹℃煋绾跨储鏁版嵁瀵癸紝鐢熸垚鏍煎紡鍖栫殑浠诲姟鍒楄〃
+     * @param missionClues 浠诲姟-姹℃煋绾跨储鏁版嵁瀵瑰垪琛紝Pair.first涓轰换鍔″璞★紝Pair.second涓哄搴旀薄鏌撶嚎绱�
+     * @return 鏍囧噯鍖栫殑璧拌埅浠诲姟淇℃伅鍒楄〃锛屽寘鍚换鍔″熀鏈睘鎬у拰姹℃煋缁熻淇℃伅
+     * @see MissionInventory 浠诲姟娓呭崟鐢熸垚鍣紝灏佽鍏蜂綋鏍煎紡鍖栭�昏緫
+     */
+    override fun generateMissionList(missionClues: List<Pair<Mission, List<PollutedClue?>>>): List<MissionInventory.MissionInfo> {
+        return MissionInventory().generateMissionList(missionClues)
+    }
+
+    /**
+     * 鐢熸垚璧拌埅浠诲姟璇︽儏锛堟寜鏃堕棿鍜屽尯鍩熺瓫閫夛級
+     * 鏍规嵁鏃堕棿鑼冨洿鍜岃鏀垮尯鍒掓煡璇换鍔★紝鏁村悎瀹炴椂鐩戞祴鏁版嵁鐢熸垚璇︾粏浠诲姟鎶ュ憡
+     * @param startTime 鏌ヨ璧峰鏃堕棿锛堝寘鍚級
+     * @param endTime 鏌ヨ缁撴潫鏃堕棿锛堝寘鍚級
+     * @param areaVo 鍖哄煙鍙傛暟锛屽寘鍚渷銆佸競銆佸尯缂栫爜
+     * @return 浠诲姟璇︽儏鍒楄〃锛屾瘡涓厓绱犲寘鍚换鍔″畬鏁翠俊鎭�佹薄鏌撶嚎绱㈠強瀹炴椂鐩戞祴鏁版嵁
+     * @see MissionRep.findByAreaAndTime 鍖哄煙鏃堕棿绛涢�夋暟鎹簮
+     * @see realTimeDataRep.fetchData 瀹炴椂鏁版嵁鑾峰彇鎺ュ彛
+     */
+    override fun generateMissionDetail(startTime: Date, endTime: Date, areaVo: AreaVo): List<MissionInventory.MissionDetail> {
+        val missionCluesData = missionRep.findByAreaAndTime(areaVo, startTime, endTime).filterNotNull().map {
+            Triple(
+                it,
+                sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>,
+                realTimeDataRep.fetchData(it)
+            )
+        }
+        val keyScenes = sceneInfoRep.findBySceneTypes(
+            listOf(
+                SceneType.TYPE19.value,
+                SceneType.TYPE20.value,
+                SceneType.TYPE21.value
+            )
+        )
+        return generateMissionDetail(keyScenes, missionCluesData)
+    }
+
+    /**
+     * 鐢熸垚璧拌埅浠诲姟璇︽儏锛堢洿鎺ュ鐞嗕换鍔℃暟鎹級
+     * 鎺ユ敹宸插叧鑱旂殑浠诲姟-姹℃煋绾跨储-瀹炴椂鏁版嵁涓夊厓缁勶紝鐢熸垚璇︾粏浠诲姟鎶ュ憡
+     * @param keyScenes 鍏抽敭鍦烘櫙鍒楄〃锛岀敤浜庡垎鏋愯蛋鑸槸鍚︾粡杩囪鍖哄煙
+     * @param missionCluesData 浠诲姟鏁版嵁涓夊厓缁勫垪琛紝Triple鍒嗗埆涓轰换鍔″璞°�佹薄鏌撶嚎绱㈠垪琛ㄣ�佸疄鏃舵暟鎹垪琛�
+     * @return 鏍囧噯鍖栫殑浠诲姟璇︽儏鍒楄〃锛屽寘鍚畬鏁寸殑浠诲姟灞炴�с�佹薄鏌撳垎鏋愬拰鐩戞祴鏁版嵁缁熻
+     * @see MissionInventory.generateMissionDetail 璇︽儏鐢熸垚鏍稿績閫昏緫
+     */
+    override fun generateMissionDetail(
+        keyScenes: List<SceneInfo?>,
+        missionCluesData: List<Triple<Mission, List<PollutedClue?>, List<BaseRealTimeData>>>,
+    ): List<MissionInventory.MissionDetail> {
+        return missionCluesData.map {
+            MissionInventory().generateMissionDetail(keyScenes, it.first, it.second, it.third)
+        }
+    }
+
+    override fun generateClueByRiskArea(
+        startTime: Date,
+        endTime: Date,
+        areaVo: AreaVo,
+    ): List<MissionRiskArea.ClueByArea> {
+        val clues = mutableListOf<PollutedClue?>()
+        missionRep.findByAreaAndTime(areaVo, startTime, endTime).onEach {
+            it ?: return@onEach
+            val clue = sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>
+            clues.addAll(clue)
+        }
+        val keyScenes = sceneInfoRep.findBySceneTypes(
+            listOf(
+                SceneType.TYPE19.value,
+                SceneType.TYPE20.value,
+                SceneType.TYPE21.value
+            )
+        )
+        return generateClueByRiskArea(keyScenes, clues)
+    }
+
+    override fun generateClueByRiskArea(
+        keyScenes: List<SceneInfo?>,
+        pollutedClues: List<PollutedClue?>,
+    ): List<MissionRiskArea.ClueByArea> {
+        return MissionRiskArea().generateClueByRiskArea(keyScenes, pollutedClues)
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3