From 94fee0b511279679b43e210878d3d36e5a14384b Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期二, 30 九月 2025 09:14:10 +0800
Subject: [PATCH] 2025.9.30 1. 新增走航任务统计功能

---
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt |  140 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 133 insertions(+), 7 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 9826661..abdba09 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
@@ -3,6 +3,7 @@
 import com.flightfeather.uav.biz.FactorFilter
 import com.flightfeather.uav.biz.dataanalysis.ExceptionAnalysisController
 import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
+import com.flightfeather.uav.biz.report.MissionGridFusion
 import com.flightfeather.uav.biz.report.MissionInventory
 import com.flightfeather.uav.biz.report.MissionRiskArea
 import com.flightfeather.uav.biz.report.MissionSummary
@@ -10,14 +11,15 @@
 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.entity.*
 import com.flightfeather.uav.domain.mapper.MissionMapper
 import com.flightfeather.uav.domain.repository.*
 import com.flightfeather.uav.lightshare.bean.AreaVo
+import com.flightfeather.uav.lightshare.bean.GridDataDetailMixVo
+import com.flightfeather.uav.lightshare.eunm.PollutionDegree
 import com.flightfeather.uav.lightshare.eunm.SceneType
 import com.flightfeather.uav.lightshare.service.DataAnalysisService
+import com.flightfeather.uav.lightshare.service.SatelliteDataCalculateService
 import com.flightfeather.uav.socket.eunm.FactorType
 import com.flightfeather.uav.socket.sender.MsgType
 import org.springframework.stereotype.Service
@@ -39,7 +41,9 @@
     private val locationRoadNearby: LocationRoadNearby,
     private val segmentInfoRep: SegmentInfoRep,
     private val sourceTraceRep: SourceTraceRep,
-    private val sceneInfoRep: SceneInfoRep
+    private val sceneInfoRep: SceneInfoRep,
+    private val satelliteGridRep: SatelliteGridRep,
+    private val satelliteDataCalculateService: SatelliteDataCalculateService
 ) : DataAnalysisService {
 
     /**
@@ -104,6 +108,13 @@
         return summary
     }
 
+    override fun generateMissionSummary(missionCode: String): MissionSummary.Summary {
+        val mission = missionRep.findOne(missionCode) ?: throw BizException("璧拌埅浠诲姟涓嶅瓨鍦�")
+        val clues = sourceTraceRep.fetchList(mission.deviceCode, mission.startTime, mission.endTime, MsgType.PolClue) as List<PollutedClue?>
+        val summary = MissionSummary().execute(mission.startTime, mission.endTime, listOf(mission), clues)
+        return summary
+    }
+
     /**
      * 鐢熸垚璧拌埅浠诲姟娓呭崟锛堟寜鏃堕棿鍜屽尯鍩熺瓫閫夛級
      * 鏍规嵁鏃堕棿鑼冨洿鍜岃鏀垮尯鍒掓煡璇㈣蛋鑸换鍔★紝骞跺叧鑱旀薄鏌撶嚎绱㈡暟鎹敓鎴愪换鍔″垪琛�
@@ -115,10 +126,25 @@
      * @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?>
+//        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)
+        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)
+            )
         }
-        return generateMissionList(missionClues)
+        val keyScenes = sceneInfoRep.findBySceneTypes(
+            listOf(
+                SceneType.TYPE19.value,
+                SceneType.TYPE20.value,
+                SceneType.TYPE21.value
+            )
+        )
+        return generateMissionInfo(keyScenes, missionCluesData)
     }
 
     /**
@@ -130,6 +156,15 @@
      */
     override fun generateMissionList(missionClues: List<Pair<Mission, List<PollutedClue?>>>): List<MissionInventory.MissionInfo> {
         return MissionInventory().generateMissionList(missionClues)
+    }
+
+    override fun generateMissionInfo(
+        keyScenes: List<SceneInfo?>,
+        missionCluesData: List<Triple<Mission, List<PollutedClue?>, List<BaseRealTimeData>>>,
+    ): List<MissionInventory.MissionInfo> {
+        return missionCluesData.map {
+            MissionInventory().generateMissionInfo(keyScenes, it.first, it.second, it.third)
+        }
     }
 
     /**
@@ -158,6 +193,20 @@
             )
         )
         return generateMissionDetail(keyScenes, missionCluesData)
+    }
+
+    override fun generateMissionDetail(missionCode: String): MissionInventory.MissionDetail {
+        val mission = missionRep.findOne(missionCode) ?: throw BizException("浠诲姟涓嶅瓨鍦�")
+        val missionClues = sourceTraceRep.fetchList(mission.deviceCode, mission.startTime, mission.endTime, MsgType.PolClue) as List<PollutedClue?>
+        val realTimeData = realTimeDataRep.fetchData(mission)
+        val keyScenes = sceneInfoRep.findBySceneTypes(
+            listOf(
+                SceneType.TYPE19.value,
+                SceneType.TYPE20.value,
+                SceneType.TYPE21.value
+            )
+        )
+        return MissionInventory().generateMissionDetail(keyScenes, mission, missionClues, realTimeData)
     }
 
     /**
@@ -198,10 +247,87 @@
         return generateClueByRiskArea(keyScenes, clues)
     }
 
+    override fun generateClueByRiskArea(missionCode: String): List<MissionRiskArea.ClueByArea> {
+        val mission = missionRep.findOne(missionCode) ?: throw BizException("浠诲姟涓嶅瓨鍦�")
+        val pollutedClues = sourceTraceRep.fetchList(mission.deviceCode, mission.startTime, mission.endTime, MsgType.PolClue) as List<PollutedClue?>
+        val keyScenes = sceneInfoRep.findBySceneTypes(
+            listOf(
+                SceneType.TYPE19.value,
+                SceneType.TYPE20.value,
+                SceneType.TYPE21.value
+            )
+        )
+        return generateClueByRiskArea(keyScenes, pollutedClues)
+    }
+
     override fun generateClueByRiskArea(
         keyScenes: List<SceneInfo?>,
         pollutedClues: List<PollutedClue?>,
     ): List<MissionRiskArea.ClueByArea> {
         return MissionRiskArea().generateClueByRiskArea(keyScenes, pollutedClues)
     }
+
+    override fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        startTime: Date,
+        endTime: Date,
+        areaVo: AreaVo,
+    ): List<MissionGridFusion.GridFusionByAQI> {
+        val gridLen = 100
+        // 鏌ヨ100绫崇綉鏍肩殑鍏蜂綋缃戞牸鏁版嵁
+        val gridGroup = satelliteGridRep.fetchGridGroup(GridGroup().apply {
+            type = "sub"
+            length = gridLen.toDouble()
+            provinceCode = areaVo.provinceCode
+            cityCode = areaVo.cityCode
+            districtCode = areaVo.districtCode
+        }).firstOrNull() ?: throw BizException("鏈煡璇㈠埌100绫崇綉鏍�")
+        val gridCells = satelliteGridRep.fetchGridCell(gridGroup.id).filterNotNull()
+        // 鏌ヨ鑼冨洿鍐呯殑鎵�鏈夎蛋鑸换鍔�
+        val missions = missionRep.findByAreaAndTime(areaVo, startTime, endTime)
+        // 鏍规嵁绌烘皵璐ㄩ噺绛夌骇鍒嗙被
+        val missionGroups = missions.groupBy { PollutionDegree.getByDes(it?.pollutionDegree ?: "") }
+        // 鏌ヨ姣忎釜绛夌骇涓嬬殑璧拌埅浠诲姟瀵瑰簲鐨勭綉鏍兼暟鎹紙濡傛灉娌℃湁鏁版嵁鍒欏墧闄よ浠诲姟锛�
+        val gridDataDetailList = missionGroups.mapNotNull { (degree, missionList) ->
+            // 绛涢�夊嚭鏈夌綉鏍艰瀺鍚堟暟鎹殑璧拌埅浠诲姟(鍚屾椂鑾峰彇瀵瑰簲鐨勮瀺鍚堟暟鎹甶d鍒楄〃)
+            val gridDataIds = mutableListOf<Int>()
+            val validMissions = missionList.filter {mission ->
+                val gridData = satelliteGridRep.fetchGridData(GridData().apply { missionCode = mission?.missionCode }).firstOrNull()
+                val res = gridData != null
+                if (res) gridDataIds.add(gridData?.id ?: 0)
+                res
+            }
+            // 鍚堝苟姣忎釜绛夌骇涓嬬殑缃戞牸鏁版嵁
+            val gridDataDetailMixVos = satelliteDataCalculateService.mixUnderwayGridData(gridGroup.id, gridDataIds)
+            // 缁熻姣忎釜璧拌埅浠诲姟鐨勮蛋鑸鎯呬俊鎭�
+            val missionCluesData = validMissions.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
+                )
+            )
+            val missionInfos = generateMissionInfo(keyScenes, missionCluesData)
+
+            return@mapNotNull Triple(degree, missionInfos, gridDataDetailMixVos)
+        }.filter { it.second.isNotEmpty() }
+
+        return generateGridFusion(factorTypes, gridLen, gridCells, gridDataDetailList)
+    }
+
+    override fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        gridLen: Int,
+        gridCells: List<GridCell>,
+        dataList: List<Triple<PollutionDegree, List<MissionInventory.MissionInfo>, List<GridDataDetailMixVo>>>,
+    ): List<MissionGridFusion.GridFusionByAQI> {
+        return MissionGridFusion(sceneInfoRep).generateGridFusion(factorTypes, gridLen, gridCells, dataList)
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3