src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt
@@ -1,5 +1,7 @@
package com.flightfeather.uav.lightshare.service.impl
import com.flightfeather.uav.common.exception.BizException
import com.flightfeather.uav.common.utils.FileExchange
import com.flightfeather.uav.domain.entity.GridCell
import com.flightfeather.uav.domain.entity.GridData
import com.flightfeather.uav.domain.entity.GridDataDetail
@@ -7,10 +9,17 @@
import com.flightfeather.uav.domain.repository.SatelliteGridRep
import com.flightfeather.uav.lightshare.bean.AreaVo
import com.flightfeather.uav.lightshare.bean.DataHead
import com.flightfeather.uav.lightshare.bean.GridDataImportResult
import com.flightfeather.uav.lightshare.service.SatelliteTelemetryService
import com.github.pagehelper.PageHelper
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import java.io.ByteArrayInputStream
import java.io.File
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
import javax.servlet.http.HttpServletResponse
/**
 *
@@ -20,6 +29,7 @@
@Service
class SatelliteTelemetryServiceImpl(private val satelliteGridRep: SatelliteGridRep) : SatelliteTelemetryService {
    private val fileExchange = FileExchange()
    override fun fetchGridGroup(areaVo: AreaVo, page: Int?, perPage: Int?): Pair<DataHead, List<GridGroup?>> {
        val pageInfo = PageHelper.startPage<GridGroup>(page ?: 1, perPage ?: 100)
        val res = satelliteGridRep.fetchGridGroup(areaVo)
@@ -37,4 +47,65 @@
    override fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> {
        return satelliteGridRep.fetchGridDataDetail(dataId, groupId, cellId)
    }
    override fun importGridData(groupId: Int, type: Int?, dataTime: LocalDateTime?, update: Int?, file: MultipartFile): GridDataImportResult? {
        val gridData = satelliteGridRep.fetchGridData(groupId, dataTime, type)
        if (!file.contentType!!.startsWith("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
            throw BizException("文件类型错误,请上传xlsx类型文件")
        }
        if (gridData.isNotEmpty() && update == 0) {
            return GridDataImportResult(false, "数据库对应网格组和日期下已存在遥测数据")
        }
        val exchangeGridDataDetails
                = fileExchange.exchangeGridData(ByteArrayInputStream(file.bytes))
        val gridCellsInDB = satelliteGridRep.fetchGridCell(groupId)
        val setA = gridCellsInDB.asSequence().map { it?.id ?: -1 }.toSet()
        val setB = exchangeGridDataDetails.asSequence().map { it.cellId ?: -1 }.toSet()
        // excel 中缺少的的单元格
        val onlyInA = setA - setB
        // excel 中多出的的单元格
        val onlyInB = setB - setA
        if (onlyInA.isNotEmpty()) {
            throw BizException("导入数据中缺少以下网格单元格:${onlyInA.joinToString(",")}")
        }
        if (onlyInB.isNotEmpty()) {
            throw BizException("导入数据中有多余网格单元格:${onlyInB.joinToString(",")}")
        }
        if (update == 1) {
            exchangeGridDataDetails.forEach {
                it.dataId = gridData[0]?.id
                it.groupId = gridData[0]?.groupId
            }
            satelliteGridRep.updatePM25Batch(exchangeGridDataDetails)
            return GridDataImportResult(true, "覆盖成功")
        }
        val gridDataEntity = GridData()
        gridDataEntity.groupId = groupId
        gridDataEntity.dataTime = dataTime?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli()
            ?.let { Date(it) }
        gridDataEntity.type = type?.toByte()
        satelliteGridRep.insertGridDataAndDetail(gridDataEntity, exchangeGridDataDetails)
        return GridDataImportResult(true, "导入成功")
    }
    override fun downloadTemplate(response: HttpServletResponse): Boolean {
        val fileName = "GridData-PM2.5-Template.xlsx"
        val path = (Thread.currentThread().contextClassLoader?.getResource("/")?.path
            ?: "src/main/resources") + "/templates/" + fileName
        val file = File(path)
        if (file.exists()) {
            val fName = Base64.getEncoder().encodeToString(fileName.toByteArray())
            response.apply {
                setHeader("Content-Disposition", "attachment;filename=$fName")
                setHeader("fileName", fName)
                addHeader("Access-Control-Expose-Headers", "fileName")
                contentType = "application/vnd.ms-excel;charset=UTF-8"
                setHeader("Pragma", "no-cache")
                setHeader("Cache-Control", "no-cache")
                setDateHeader("Expires", 0)
            }
            response.outputStream.write(file.readBytes())
        }
        return true
    }
}