package com.flightfeather.uav.biz.report
|
|
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.dataprocess.PreData
|
import com.flightfeather.uav.common.chart.DataToChartUtil
|
import com.flightfeather.uav.common.exception.BizException
|
import com.flightfeather.uav.common.location.LocationRoadNearby
|
import com.flightfeather.uav.common.pdf.GeneratePdfUtil
|
import com.flightfeather.uav.common.utils.DateUtil
|
import com.flightfeather.uav.common.utils.ImageUtil
|
import com.flightfeather.uav.domain.entity.Mission
|
import com.flightfeather.uav.domain.repository.MissionRep
|
import com.flightfeather.uav.domain.repository.RealTimeDataRep
|
import com.flightfeather.uav.domain.repository.SegmentInfoRep
|
import org.springframework.beans.BeanUtils
|
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.stereotype.Component
|
import java.time.LocalDateTime
|
import java.time.ZoneId
|
import java.time.format.DateTimeFormatter
|
|
/**
|
* 走航任务报告
|
*/
|
@Component
|
class MissionReport(
|
private val missionRep: MissionRep,
|
private val realTimeDataRep: RealTimeDataRep,
|
private val locationRoadNearby: LocationRoadNearby,
|
private val segmentInfoRep: SegmentInfoRep,
|
@Value("\${filePath}")
|
private val filePath: String,
|
) {
|
|
private val exceptionAnalysisController =
|
ExceptionAnalysisController(realTimeDataRep, locationRoadNearby, segmentInfoRep)
|
|
data class Param(
|
val district: String,
|
val town: String,
|
val year: Int,
|
val month: Int,
|
val day: Int,
|
val first_party: String,
|
val start_time: String,
|
val end_time: String,
|
) {
|
var factor_names: String = ""
|
var summary: List<Summary> = emptyList()
|
set(value) {
|
factor_names = value.map { it.factor }.joinToString("、")
|
field = value
|
}
|
var exceptions: List<ExceptionChart> = emptyList()
|
|
/**
|
* 传入数据异常集合,自动为每条异常生成折线图
|
*/
|
fun addExceptions(exceptions: List<ExceptionResult>) {
|
this.exceptions = exceptions.map {
|
val c = ExceptionChart()
|
BeanUtils.copyProperties(it, c)
|
// 创建主污染因子的数据折线图
|
val byteArray = DataToChartUtil.lineToByteArray(it.selectedFactor?.main, it.dataList)
|
val base64Str = ImageUtil.compressImage2(byteArray, 800, needPrefix = false)
|
c.mainPict = base64Str
|
// 创建关联因子的数据折线图
|
if (it.selectedFactor?.subs?.isNotEmpty() == true) {
|
val subList = mutableListOf<String>()
|
it.selectedFactor!!.subs.forEach { type ->
|
val byteArray1 = DataToChartUtil.lineToByteArray(type, it.dataList)
|
val base64Str1 = ImageUtil.compressImage2(byteArray1, 800, needPrefix = false)
|
subList.add(base64Str1)
|
}
|
c.subPictList = subList
|
}
|
return@map c
|
}
|
}
|
}
|
|
/**
|
* 数据统计
|
*/
|
class Summary {
|
var id: String? = null
|
var factor: String? = null
|
var avg: Double? = null
|
var min: Double? = null
|
var max: Double? = null
|
|
// 数据折线图Base64编码
|
var pict: String? = null
|
}
|
|
/**
|
* 数据异常所在时段的折线图
|
*/
|
class ExceptionChart : ExceptionResult() {
|
// 污染因子的异常数据折线图Base64编码
|
var mainPict: String? = null
|
|
// 关联因子的异常数据折线图Base64编码
|
var subPictList: List<String>? = null
|
}
|
|
private val templateName = "report-underway.ftl"
|
|
private val dateFormatter = DateTimeFormatter.ofPattern("HH:mm")
|
|
// 获取异常分析结果
|
fun exceptionAnalysis(mission: Mission, factorFilter: FactorFilter): List<ExceptionResult> {
|
return exceptionAnalysisController.execute(mission, factorFilter)
|
}
|
|
// 计算均值和数据范围
|
fun dataSummary(mission: Mission, factorFilter: FactorFilter): List<Summary> {
|
val preData = PreData(
|
DateUtil.instance.dateToString(mission.startTime, DateUtil.DateStyle.YYYY_MM_DD),
|
factorFilter.mainList()
|
)
|
val realTimeData = realTimeDataRep.fetchData(mission)
|
realTimeData.forEach {
|
preData.add(it.toDataVo())
|
}
|
val resMap = preData.calculate()
|
|
val summaries = mutableListOf<Summary>()
|
resMap.forEach { (t, u) ->
|
summaries.add(Summary().apply {
|
id = t.value.toString()
|
factor = t.des
|
avg = u.avg
|
min = u.min
|
max = u.max
|
|
val byteArray = DataToChartUtil.lineToByteArray(t, realTimeData)
|
val base64Str = ImageUtil.compressImage2(byteArray, 800, needPrefix = false)
|
pict = base64Str
|
})
|
}
|
return summaries
|
}
|
|
// 生成参数
|
// 根据报告模板生成对应报告
|
fun execute(missionCode: String, factorFilter: FactorFilter): String {
|
// 1. 任务合法性检查
|
val mission = missionRep.findOne(missionCode) ?: throw BizException("该任务编号不存在")
|
// 2. 获取数据异常统计结果,根据
|
val exceptions = exceptionAnalysis(mission, factorFilter)
|
// 3. 获取均值、范围等统计数据
|
val summaries = dataSummary(mission, factorFilter)
|
// 4. 生成报告
|
val fileName = "report/" + "${mission.districtName}走航监测报告-${
|
DateUtil.instance.dateToString(mission.startTime, DateUtil.DateStyle.YYYY_MM_DD)
|
}(${mission.missionCode}).doc"
|
val reportTemplate = ReportTemplate(templateName, filePath, fileName)
|
val param = getParam(mission, exceptions, summaries)
|
val params = reportTemplate.getParam(param)
|
GeneratePdfUtil.generateWord(params)
|
return filePath + fileName
|
}
|
|
private fun getParam(mission: Mission, exceptions: List<ExceptionResult>, summaries: List<Summary>): Param {
|
val startTime = LocalDateTime.ofInstant(mission.startTime.toInstant(), ZoneId.systemDefault())
|
val endTime = LocalDateTime.ofInstant(mission.endTime.toInstant(), ZoneId.systemDefault())
|
return Param(
|
mission.districtName, "", startTime.year, startTime.monthValue, startTime.dayOfMonth, "",
|
startTime.format(dateFormatter), endTime.format(dateFormatter)
|
).apply {
|
summary = summaries
|
addExceptions(exceptions)
|
}
|
}
|
}
|