| | |
| | | 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 |
| | | */ |
| | |
| | | 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("走航任务不存在") |
| | | |
| | |
| | | ) |
| | | } |
| | | |
| | | /** |
| | | * 获取历史污染溯源结果 |
| | | * 查询指定任务的历史污染溯源结果并序列化为JSON字符串 |
| | | * @param missionCode 走航任务编码 |
| | | * @return 历史污染溯源结果的JSON字符串,具体格式由sourceTraceRep实现决定 |
| | | * @throws BizException 当走航任务不存在时抛出 |
| | | */ |
| | | override fun fetchHistory(missionCode: String): String { |
| | | val mission = missionRep.findOne(missionCode) ?: throw BizException("走航任务不存在") |
| | | |
| | |
| | | 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) |
| | | } |
| | | } |