feiyu02
2025-09-30 94fee0b511279679b43e210878d3d36e5a14384b
src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt
@@ -2,11 +2,9 @@
import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.domain.repository.MissionRep
import com.flightfeather.uav.lightshare.bean.AreaVo
import com.flightfeather.uav.socket.eunm.FactorType
import com.flightfeather.uav.socket.sender.MsgType
import org.springframework.stereotype.Component
import java.util.*
import kotlin.math.round
@@ -16,6 +14,10 @@
 * @author feiyu02
 */
class MissionSummary() {
    companion object {
        private const val FOCUS_AREA_COUNT = 2
    }
    data class Summary(
        // 汇总周期开始时间
@@ -33,11 +35,13 @@
        // 各等级空气质量背景走航次数,<空气质量等级,次数,占比>
        val countByDegree: List<Triple<String, Int, Double>>,
        // 问题总数
        val probCount:Int,
        val probCount: Int,
        // 高风险场景总数
        val highRiskSceneCount:Int,
        val highRiskSceneCount: Int,
        // 问题按监测因子类型分布情况, <因子类型,次数,占比>
        val probByFactor:List<Triple<String, Int, Double>>
        val probByFactor: List<Triple<String, Int, Double>>,
        // 聚焦区域或场景
        val focusRegion: List<String>,
    )
    /**
@@ -61,7 +65,8 @@
                countByDegree = emptyList(),
                probCount = 0,
                highRiskSceneCount = 0,
                probByFactor = emptyList()
                probByFactor = emptyList(),
                focusRegion = emptyList()
            )
        }
@@ -94,13 +99,16 @@
            Triple(degree, count, count.toDouble() / totalCount)
        }
        // 6. 问题相关统计(示例:此处假设需关联其他表,暂返回0,实际需根据业务补充)
        // 6. 问题相关统计
        val clueRes = calClue(clues)
        val probCount = clueRes.first // 需关联问题表统计
        val highRiskSceneCount = clueRes.second // 需关联场景表统计
        val probByFactor = clueRes.third
        // 7. 构建并返回统计结果
        // 7. 从异常所在地区和溯源的场景中统计聚焦区域
        val focusRegion = calFocusRegion(clues)
        // 8. 构建并返回统计结果
        return Summary(
            startTime = startTime,
            endTime = endTime,
@@ -111,14 +119,15 @@
            countByDegree = countByDegree,
            probCount = probCount,
            highRiskSceneCount = highRiskSceneCount,
            probByFactor = probByFactor
            probByFactor = probByFactor,
            focusRegion = focusRegion
        )
    }
    private fun calClue(clues: List<PollutedClue?>): Triple<Int, Int, List<Triple<String, Int, Double>>> {
        var probCount = 0 // 需关联问题表统计
        var highRiskSceneCount = 0 // 需关联场景表统计
        val probByFactorMap = mutableMapOf<FactorType, Int>() // 需关联因子表统计
        var probCount = 0
        var highRiskSceneCount = 0
        val probByFactorMap = mutableMapOf<FactorType, Int>()
        clues.forEach { c ->
            if (c?.msgType == MsgType.PolClue.value) {
                c.pollutedSource?.sceneList?.size?.let { s -> highRiskSceneCount += s }
@@ -137,4 +146,32 @@
        }
        return Triple(probCount, highRiskSceneCount, probByFactor)
    }
    private fun calFocusRegion(clues: List<PollutedClue?>): List<String> {
        // 统计每个区域或场景出现的次数
        val focusArea = mutableMapOf<String, Int>()
        val focusScene = mutableMapOf<String, Int>()
        clues.forEach { c->
            if (c?.msgType == MsgType.PolClue.value) {
                if (!c.pollutedArea?.address.isNullOrBlank()) {
                    if (focusArea.containsKey(c.pollutedArea?.address)) {
                        focusArea[c.pollutedArea?.address!!] = focusArea[c.pollutedArea?.address]!! + 1
                    } else {
                        focusArea[c.pollutedArea?.address!!] = 1
                    }
                }
                c.pollutedSource?.sceneList?.forEach { s->
                    if (s.name != null) {
                        if (focusScene.containsKey(s.name!!)) {
                            focusScene[s.name!!] = focusScene[s.name!!]!! + 1
                        } else {
                            focusScene[s.name!!] = 1
                        }
                    }
                }
            }
        }
        return focusArea.entries.sortedByDescending { it.value }.map { it.key }.take(FOCUS_AREA_COUNT) +
                focusScene.entries.sortedByDescending { it.value }.map { it.key }.take(FOCUS_AREA_COUNT)
    }
}