src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt
@@ -2,10 +2,15 @@ import com.alibaba.fastjson.JSONObject import com.flightfeather.uav.common.exception.BizException import com.flightfeather.uav.domain.entity.GridAodDetail import com.flightfeather.uav.domain.entity.GridDataDetail import com.flightfeather.uav.domain.entity.RealTimeData import com.flightfeather.uav.domain.entity.RealTimeDataVehicle import com.flightfeather.uav.socket.bean.AirData import org.apache.poi.hssf.usermodel.HSSFWorkbook import org.apache.poi.ss.usermodel.Cell import org.apache.poi.ss.usermodel.CellType import org.apache.poi.ss.util.CellAddress import org.apache.poi.xssf.streaming.SXSSFWorkbook import java.io.File import java.io.FileInputStream @@ -53,7 +58,7 @@ if (cellIterator.hasNext()) { val cellText = cellIterator.next().stringCellValue if (!cellText.equals(head)) { throw BizException("æä»¶æ ¼å¼é误, 表头[${head}]åºè¯¥ä¸º[${cellText}]") throw BizException("æä»¶æ ¼å¼é误, 表头[${cellText}]åºè¯¥ä¸º[${head}]") } } else { throw BizException("æä»¶æ ¼å¼é误, 表头[${head}]缺失") @@ -93,6 +98,192 @@ } /** * 转æ¢PM2.5è¡¨æ ¼æ°æ® */ fun exchangeGridData(file: InputStream, correctRangeGridCells: Set<Int>): List<GridDataDetail> { // 模仿已æä»£ç å¤æè¡¨å¤´æ£ç¡®æ§ å¹¶å¨éè¯¯æ¶æåºå¼å¸¸ val headers = listOf( "pointid", "PM2.5" ) val result = mutableListOf<GridDataDetail>() try { ExcelUtil.readXLXS(file, headerCheck = { val cellIterator = it.cellIterator() val headIterator = headers.iterator() while (headIterator.hasNext()) { val head = headIterator.next() if (cellIterator.hasNext()) { val cellText = cellIterator.next().stringCellValue if (!cellText.equals(head)) { throw BizException("æä»¶æ ¼å¼é误, 表头[${cellText}]åºè¯¥ä¸º[${head}]") } } else { throw BizException("æä»¶æ ¼å¼é误, 表头[${head}]缺失") } } true }, // 夿åå æ ¼æ°æ®æ£ç¡®æ§ï¼å¹¶å¨æ¥éåæåºå¼å¸¸ onRow = { val data = GridDataDetail().apply { // 转æ¢ç½æ ¼ç»åå æ ¼id // å¾å°å½ååå æ ¼çå®ä½ä¿¡æ¯ ï¼eg: B3,BA3...ï¼ val cellIdCellPosStr = CellAddress(it.rowNum, 0).formatAsString() // å¾å°å½ååå æ ¼æ°æ®ç±»å val cellIdCellType = it.getCell(0).cellType when (cellIdCellType) { CellType.NUMERIC -> { // å½å¼ä¸ºæ°åç±»åæ¶è½¬åä¸ºç½æ ¼åå æ ¼id this.cellId = it.getCell(0)?.numericCellValue?.toInt() } else -> { throw BizException("åå æ ¼[${cellIdCellPosStr}]䏿¯æ°åç±»å") } } // 转æ¢PM2.5 // å¾å°å½ååå æ ¼çå®ä½ä¿¡æ¯ ï¼eg: B3,BA3...ï¼ val pm25CellPosStr = CellAddress(it.rowNum, 1).formatAsString() // å¾å°å½ååå æ ¼æ°æ®ç±»å val pm25CellType = it.getCell(1).cellType when (pm25CellType) { CellType.STRING -> { // å½å¼ä¸ºåç¬¦ä¸²æ¶æä¸¤ç§æ åµ // ç©ºç½æè æ¯â/âå符 转åä¸ºç©ºå¼ // å¦åæ¥é val stringValue = it.getCell(1)?.stringCellValue?.trim() if (stringValue != null) { if (stringValue == "/" || stringValue.isBlank()) { this.pm25 = null } }else { throw BizException("åå æ ¼[${pm25CellPosStr}]䏿¯æ°åç±»åæè ææ¬ç±»å") } } CellType.NUMERIC -> { // å½å¼ä¸ºæ°åç±»åæ¶è½¬å为pm2.5æ°æ® this.pm25 = it.getCell(1)?.numericCellValue?.toFloat() } else -> { throw BizException("åå æ ¼[${pm25CellPosStr}]䏿¯æ°åç±»å") } } } result.add(data) }) } catch (e: BizException) { throw e } // å¤æç½æ ¼åå æ ¼ç¼å·æ¯å¦å¨æ£ç¡®çèå´å val resultCellIdSet = result.asSequence().map { it.cellId ?: -1 }.toSet() // ç¨æ·å¯¼å ¥ä¸ç¼ºå°ççåå æ ¼ val shortCells = correctRangeGridCells - resultCellIdSet // excel ä¸å¤åºççåå æ ¼ val outCells = resultCellIdSet - correctRangeGridCells if (shortCells.isNotEmpty()) { throw BizException("å¯¼å ¥æ°æ®ä¸ç¼ºå°ä»¥ä¸ç½æ ¼åå æ ¼ï¼${shortCells.joinToString(",")}") } if (outCells.isNotEmpty()) { throw BizException("å¯¼å ¥æ°æ®ä¸æå¤ä½ç½æ ¼åå æ ¼ï¼${outCells.joinToString(",")}") } return result } /** * 转æ¢AODè¡¨æ ¼æ°æ® */ fun exchangeGridAod(file: InputStream, correctRangeGridCells: Set<Int>): List<GridAodDetail> { // 模仿已æä»£ç å¤æè¡¨å¤´æ£ç¡®æ§ å¹¶å¨éè¯¯æ¶æåºå¼å¸¸ val headers = listOf( "pointid", "AOD" ) val result = mutableListOf<GridAodDetail>() try { ExcelUtil.readXLXS(file, headerCheck = { val cellIterator = it.cellIterator() val headIterator = headers.iterator() while (headIterator.hasNext()) { val head = headIterator.next() if (cellIterator.hasNext()) { val cellText = cellIterator.next().stringCellValue if (!cellText.equals(head)) { throw BizException("æä»¶æ ¼å¼é误, 表头[${cellText}]åºè¯¥ä¸º[${head}]") } } else { throw BizException("æä»¶æ ¼å¼é误, 表头[${head}]缺失") } } true }, // 夿åå æ ¼æ°æ®æ£ç¡®æ§ï¼å¹¶å¨æ¥éåæåºå¼å¸¸ onRow = { val data = GridAodDetail().apply { // 转æ¢ç½æ ¼ç»åå æ ¼id // å¾å°å½ååå æ ¼çå®ä½ä¿¡æ¯ ï¼eg: B3,BA3...ï¼ val cellIdCellPosStr = CellAddress(it.rowNum, 0).formatAsString() // å¾å°å½ååå æ ¼æ°æ®ç±»å val cellIdCellType = it.getCell(0).cellType when (cellIdCellType) { CellType.NUMERIC -> { // å½å¼ä¸ºæ°åç±»åæ¶è½¬åä¸ºç½æ ¼åå æ ¼id this.cellId = it.getCell(0)?.numericCellValue?.toInt() } else -> { throw BizException("åå æ ¼[${cellIdCellPosStr}]䏿¯æ°åç±»å") } } // 转æ¢AOD // å¾å°å½ååå æ ¼çå®ä½ä¿¡æ¯ ï¼eg: B3,BA3...ï¼ val aodCellPosStr = CellAddress(it.rowNum, 1).formatAsString() // å¾å°å½ååå æ ¼æ°æ®ç±»å val aodCellType = it.getCell(1).cellType when (aodCellType) { CellType.STRING -> { // å½å¼ä¸ºåç¬¦ä¸²æ¶æä¸¤ç§æ åµ // ç©ºç½æè æ¯â/âå符 转åä¸ºç©ºå¼ // å¦åæ¥é val stringValue = it.getCell(1)?.stringCellValue?.trim() if (stringValue != null) { if (stringValue == "/" || stringValue.isBlank()) { this.aod = null } }else { throw BizException("åå æ ¼[${aodCellPosStr}]䏿¯æ°åç±»åæè ææ¬ç±»å") } } CellType.NUMERIC -> { // å½å¼ä¸ºæ°åç±»åæ¶è½¬å为pm2.5æ°æ® this.aod = it.getCell(1)?.numericCellValue?.toFloat() } else -> { throw BizException("åå æ ¼[${aodCellPosStr}]䏿¯æ°åç±»å") } } } result.add(data) }) } catch (e: BizException) { throw e } // å¤æç½æ ¼åå æ ¼ç¼å·æ¯å¦å¨æ£ç¡®çèå´å val resultCellIdSet = result.asSequence().map { it.cellId ?: -1 }.toSet() // ç¨æ·å¯¼å ¥ä¸ç¼ºå°ççåå æ ¼ val shortCells = correctRangeGridCells - resultCellIdSet // excel ä¸å¤åºççåå æ ¼ val outCells = resultCellIdSet - correctRangeGridCells if (shortCells.isNotEmpty()) { throw BizException("å¯¼å ¥æ°æ®ä¸ç¼ºå°ä»¥ä¸ç½æ ¼åå æ ¼ï¼${shortCells.joinToString(",")}") } if (outCells.isNotEmpty()) { throw BizException("å¯¼å ¥æ°æ®ä¸æå¤ä½ç½æ ¼åå æ ¼ï¼${outCells.joinToString(",")}") } return result } /** * 转æ¢è½¦è½½èµ°èªæ°æ® */ fun exchangeVehicleData(deviceCode: String, file: InputStream): List<RealTimeDataVehicle> { src/main/kotlin/com/flightfeather/uav/domain/entity/GridAod.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,59 @@ package com.flightfeather.uav.domain.entity; import javax.persistence.*; import java.util.Date; @Table(name = "grid_aod") public class GridAod { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "group_id") private Integer groupId; @Column(name = "data_time") private Date dataTime; /** * @return id */ public Integer getId() { return id; } /** * @param id */ public void setId(Integer id) { this.id = id; } /** * @return group_id */ public Integer getGroupId() { return groupId; } /** * @param groupId */ public void setGroupId(Integer groupId) { this.groupId = groupId; } /** * @return data_time */ public Date getDataTime() { return dataTime; } /** * @param dataTime */ public void setDataTime(Date dataTime) { this.dataTime = dataTime; } } src/main/kotlin/com/flightfeather/uav/domain/entity/GridAodDetail.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,92 @@ package com.flightfeather.uav.domain.entity; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; @Table(name = "grid_aod_detail") public class GridAodDetail { @Id private Integer id; @Column(name = "aod_id") private Integer aodId; @Column(name = "group_id") private Integer groupId; @Column(name = "cell_id") private Integer cellId; private Float aod; /** * @return id */ public Integer getId() { return id; } /** * @param id */ public void setId(Integer id) { this.id = id; } /** * @return aod_id */ public Integer getAodId() { return aodId; } /** * @param aodId */ public void setAodId(Integer aodId) { this.aodId = aodId; } /** * @return group_id */ public Integer getGroupId() { return groupId; } /** * @param groupId */ public void setGroupId(Integer groupId) { this.groupId = groupId; } /** * @return cell_id */ public Integer getCellId() { return cellId; } /** * @param cellId */ public void setCellId(Integer cellId) { this.cellId = cellId; } /** * @return aod */ public Float getAod() { return aod; } /** * @param aod */ public void setAod(Float aod) { this.aod = aod; } } src/main/kotlin/com/flightfeather/uav/domain/entity/GridData.java
@@ -6,6 +6,7 @@ @Table(name = "grid_data") public class GridData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; /** src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodDetailMapper.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,8 @@ package com.flightfeather.uav.domain.mapper import com.flightfeather.uav.domain.MyMapper import com.flightfeather.uav.domain.entity.GridAodDetail import org.apache.ibatis.annotations.Mapper @Mapper interface GridAodDetailMapper : MyMapper<GridAodDetail?> src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodMapper.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,8 @@ package com.flightfeather.uav.domain.mapper import com.flightfeather.uav.domain.MyMapper import com.flightfeather.uav.domain.entity.GridAod import org.apache.ibatis.annotations.Mapper @Mapper interface GridAodMapper : MyMapper<GridAod?> src/main/kotlin/com/flightfeather/uav/domain/mapper/GridDataDetailMapper.kt
@@ -5,4 +5,6 @@ import org.apache.ibatis.annotations.Mapper @Mapper interface GridDataDetailMapper : MyMapper<GridDataDetail?> interface GridDataDetailMapper : MyMapper<GridDataDetail?> { fun updatePM25Batch(gridDataDetails: List<GridDataDetail>) } src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt
@@ -1,9 +1,8 @@ package com.flightfeather.uav.domain.repository import com.flightfeather.uav.domain.entity.GridCell import com.flightfeather.uav.domain.entity.GridData import com.flightfeather.uav.domain.entity.GridDataDetail import com.flightfeather.uav.domain.entity.GridGroup import com.flightfeather.uav.domain.entity.* import com.flightfeather.uav.domain.mapper.GridAodDetailMapper import com.flightfeather.uav.domain.mapper.GridAodMapper import com.flightfeather.uav.domain.mapper.GridCellMapper import com.flightfeather.uav.domain.mapper.GridDataDetailMapper import com.flightfeather.uav.domain.mapper.GridDataMapper @@ -24,6 +23,8 @@ private val gridCellMapper: GridCellMapper, private val gridDataMapper: GridDataMapper, private val gridDataDetailMapper: GridDataDetailMapper, private val gridAodMapper: GridAodMapper, private val gridAodDetailMapper: GridAodDetailMapper, ) { fun fetchGridGroup(areaVo: AreaVo): List<GridGroup?> { @@ -59,4 +60,56 @@ orderBy("cellId") }) } fun insertGridDataAndDetail(data: GridData, gridDataDetails: List<GridDataDetail>) { gridDataMapper.insert(data) gridDataDetails.forEach { it.dataId = data.id it.groupId = data.groupId } gridDataDetailMapper.insertList(gridDataDetails) } fun updatePM25Batch(gridDataDetails: List<GridDataDetail>) { gridDataDetailMapper.updatePM25Batch(gridDataDetails) } // aod ç¸å ³æä½ fun fetchGridAod(groupId: Int, dataTime: LocalDateTime?): List<GridAod?> { return gridAodMapper.selectByExample(Example(GridAod::class.java).apply { createCriteria().andEqualTo("groupId", groupId) .andEqualTo("dataTime", dataTime) }) } fun fetchGridAodDetail(aodId: Int, groupId: Int?, cellId: Int?): List<GridAodDetail?> { return gridAodDetailMapper.selectByExample(Example(GridAodDetail::class.java).apply { createCriteria().andEqualTo("aodId", aodId) .andEqualTo("groupId", groupId) .andEqualTo("cellId", cellId) orderBy("cellId") }) } fun insertGridAodAndDetail(aod: GridAod, gridAodDetails: List<GridAodDetail>) { gridAodMapper.insert(aod) gridAodDetails.forEach { it.aodId = aod.id it.groupId = aod.groupId } gridAodDetailMapper.insertList(gridAodDetails) } fun updateGridAodBatch(gridDataDetails: List<GridAodDetail>) { gridDataDetails.forEach { gridAodDetailMapper.updateByExample(it, Example(GridAodDetail::class.java).apply { createCriteria().andEqualTo("aodId", it.aodId) .andEqualTo("groupId", it.groupId) .andEqualTo("cellId", it.cellId) }) } } } src/main/kotlin/com/flightfeather/uav/lightshare/bean/GridDataImportResult.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package com.flightfeather.uav.lightshare.bean import com.fasterxml.jackson.annotation.JsonInclude /** * ç½æ ¼æ°æ®å¯¼å ¥å¤çç»æ */ @JsonInclude(JsonInclude.Include.NON_NULL) data class GridDataImportResult( val success: Boolean, val result: String ) src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt
@@ -1,12 +1,17 @@ package com.flightfeather.uav.lightshare.service import com.flightfeather.uav.common.exception.BizException import com.flightfeather.uav.domain.entity.GridAod import com.flightfeather.uav.domain.entity.GridCell import com.flightfeather.uav.domain.entity.GridData import com.flightfeather.uav.domain.entity.GridDataDetail import com.flightfeather.uav.domain.entity.GridGroup import com.flightfeather.uav.lightshare.bean.AreaVo import com.flightfeather.uav.lightshare.bean.DataHead import com.flightfeather.uav.lightshare.bean.GridDataImportResult import org.springframework.web.multipart.MultipartFile import java.time.LocalDateTime import javax.servlet.http.HttpServletResponse /** * @@ -22,4 +27,16 @@ fun fetchGridData(groupId: Int, dataTime: LocalDateTime?, type: Int?): List<GridData?> fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> @Throws(BizException::class) fun importGridData(groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile): GridDataImportResult? fun downloadTemplate(response: HttpServletResponse): Boolean fun fetchGridAod(groupId: Int, dataTime: LocalDateTime?): List<GridAod?> @Throws(BizException::class) fun importGridAOD(groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile): GridDataImportResult? fun downloadAODTemplate(response: HttpServletResponse): Boolean } src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt
@@ -1,5 +1,8 @@ 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.GridAod import com.flightfeather.uav.domain.entity.GridCell import com.flightfeather.uav.domain.entity.GridData import com.flightfeather.uav.domain.entity.GridDataDetail @@ -7,10 +10,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 +30,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) @@ -34,7 +45,137 @@ return satelliteGridRep.fetchGridData(groupId, dataTime, type) } override fun fetchGridAod(groupId: Int, dataTime: LocalDateTime?): List<GridAod?> { return satelliteGridRep.fetchGridAod(groupId, dataTime) } override fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> { return satelliteGridRep.fetchGridDataDetail(dataId, groupId, cellId) } override fun importGridData(groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile): GridDataImportResult? { // å 为æ¯å¯¼å ¥å«æé¥æµæ°æ® typeå§ç»ä¸º0 val type = 0 // é¦å 夿æä»¶ç±»åï¼æä»¶ç±»å䏿¯xlsxç´æ¥æ¥é if (!file.contentType!!.startsWith("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) { throw BizException("æä»¶ç±»åé误ï¼è¯·ä¸ä¼ xlsxç±»åæä»¶") } // æ ¡éª ç¨æ·æ´æ°æä»¤ å æ°æ®åºä¸ç½æ ¼æ°æ®åå¨ä¸å¦ æ¯å¦å¹é ï¼ä¸å¹é æåºé误 // è¿ä¸ªè¿ç¨éè¦æ¥è¯¢æ°æ®åºä¸ç½æ ¼ç»æ°æ® val gridData = satelliteGridRep.fetchGridData(groupId, dataTime, type) // å°ç¨æ·å¯¼å ¥çæä»¶è½¬æ¢ä¸ºæ°æ® // 转æ¢çè¿ç¨éè¦ç½æ ¼åå æ ¼æ°æ® ä»¥å¤æç½æ ¼åå æ ¼æ¯å¦å¨æ£ç¡®çèå´å val gridCellsInDBSet = satelliteGridRep.fetchGridCell(groupId).asSequence().map { it?.id ?: -1 }.toSet() val importData = fileExchange.exchangeGridData(ByteArrayInputStream(file.bytes), gridCellsInDBSet) if (update) { // ç¨æ·éè¦æ§è¡æ´æ° if (gridData.isEmpty()) { throw BizException("æä»¤éè¯¯ï¼æ°æ®åºå¯¹åºç½æ ¼ç»åæ¥æä¸ä¸åå¨é¥æµæ°æ®ï¼è¯·æ§è¡æå ¥æä½") } importData.forEach { it.dataId = gridData[0]?.id it.groupId = gridData[0]?.groupId } satelliteGridRep.updatePM25Batch(importData) return GridDataImportResult(true, "è¦çæå") }else { // ç¨æ·éè¦æ§è¡æå ¥ if (gridData.isNotEmpty()) { throw BizException("æä»¤éè¯¯ï¼æ°æ®åºå¯¹åºç½æ ¼ç»åæ¥æä¸å·²åå¨é¥æµæ°æ®ï¼è¯·æ§è¡æ´æ°æä½") } val gridDataEntity = GridData() gridDataEntity.groupId = groupId gridDataEntity.dataTime = dataTime?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli() ?.let { Date(it) } gridDataEntity.type = type.toByte() satelliteGridRep.insertGridDataAndDetail(gridDataEntity, importData) 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 } override fun importGridAOD( groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile ): GridDataImportResult? { // é¦å 夿æä»¶ç±»åï¼æä»¶ç±»å䏿¯xlsxç´æ¥æ¥é if (!file.contentType!!.startsWith("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) { throw BizException("æä»¶ç±»åé误ï¼è¯·ä¸ä¼ xlsxç±»åæä»¶") } // æ ¡éª ç¨æ·æ´æ°æä»¤ å æ°æ®åºä¸ç½æ ¼æ°æ®åå¨ä¸å¦ æ¯å¦å¹é ï¼ä¸å¹é æåºé误 // è¿ä¸ªè¿ç¨éè¦æ¥è¯¢æ°æ®åºä¸ç½æ ¼ç»æ°æ® val gridAod = satelliteGridRep.fetchGridAod(groupId, dataTime) // å°ç¨æ·å¯¼å ¥çæä»¶è½¬æ¢ä¸ºæ°æ® // 转æ¢çè¿ç¨éè¦ç½æ ¼åå æ ¼æ°æ® ä»¥å¤æç½æ ¼åå æ ¼æ¯å¦å¨æ£ç¡®çèå´å val gridCellsInDBSet = satelliteGridRep.fetchGridCell(groupId).asSequence().map { it?.id ?: -1 }.toSet() val importAod = fileExchange.exchangeGridAod(ByteArrayInputStream(file.bytes), gridCellsInDBSet) if (update) { // ç¨æ·éè¦æ§è¡æ´æ° if (gridAod.isEmpty()) { throw BizException("æä»¤éè¯¯ï¼æ°æ®åºå¯¹åºç½æ ¼ç»åæ¥æä¸ä¸åå¨AODæ°æ®ï¼è¯·æ§è¡æå ¥æä½") } importAod.forEach { it.aodId = gridAod[0]?.id it.groupId = gridAod[0]?.groupId } satelliteGridRep.updateGridAodBatch(importAod) return GridDataImportResult(true, "è¦çæå") }else { // ç¨æ·éè¦æ§è¡æå ¥ if (gridAod.isNotEmpty()) { throw BizException("æä»¤éè¯¯ï¼æ°æ®åºå¯¹åºç½æ ¼ç»åæ¥æä¸å·²åå¨AODæ°æ®ï¼è¯·æ§è¡æ´æ°æä½") } val gridAodEntity = GridAod() gridAodEntity.groupId = groupId gridAodEntity.dataTime = dataTime?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli() ?.let { Date(it) } satelliteGridRep.insertGridAodAndDetail(gridAodEntity, importAod) return GridDataImportResult(true, "å¯¼å ¥æå") } } override fun downloadAODTemplate(response: HttpServletResponse): Boolean { val fileName = "GridData-AOD-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 } } src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt
@@ -6,8 +6,12 @@ import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam import org.springframework.format.annotation.DateTimeFormat import org.springframework.web.bind.annotation.* import org.springframework.web.multipart.MultipartFile import springfox.documentation.annotations.ApiIgnore import java.time.LocalDateTime import javax.servlet.http.HttpServletResponse /** * 嫿饿µ @@ -38,7 +42,7 @@ fun fetchGridData( @ApiParam("ç½æ ¼ç»id") @RequestParam groupId: Int, @ApiParam("饿µæ°æ®æ¶é´") @RequestParam(required = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") dataTime: LocalDateTime?, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") dataTime: LocalDateTime?, @ApiParam("饿µæ°æ®ç±»å", allowableValues = "0ï¼åå§å«æé¥æµæ°æ®ï¼1ï¼èåæ°æ®") @RequestParam(required = false) type: Int?, ) = resPack { satelliteTelemetryService.fetchGridData(groupId, dataTime, type) } @@ -49,4 +53,45 @@ @ApiParam("ç½æ ¼ç»id") @RequestParam(required = false) groupId: Int?, @ApiParam("ç½æ ¼åå æ ¼id") @RequestParam(required = false) cellId: Int?, ) = resPack { satelliteTelemetryService.fetchGridDataDetail(dataId, groupId, cellId) } @ApiOperation(value = "å¯¼å ¥å«æé¥æµPM2.5ç»ææ°æ®") @PostMapping("/import/grid/data") fun importGridData( @ApiParam("ç½æ ¼ç»id") @RequestParam groupId: Int, @ApiParam("饿µæ°æ®æ¶é´") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") dateTime: LocalDateTime, @ApiParam("è¦çæ§æ°æ® 0: ä¸è¦ç 1: è¦ç") @RequestParam update: Boolean, @RequestParam("excel") file: MultipartFile, ) = resPack { satelliteTelemetryService.importGridData(groupId, dateTime, update, file) } @ApiOperation(value = "ä¸è½½å«æé¥æµPM2.5ç»ææ°æ®å¯¼å ¥æ¨¡æ¿") @GetMapping("/import/grid/data/download/template") fun downloadTemplate(@ApiIgnore response: HttpServletResponse) = satelliteTelemetryService.downloadTemplate(response) @ApiOperation(value = "è·åç½æ ¼ç»ä¸ç嫿饿µaodæ°æ®") @GetMapping("/grid/aod") fun fetchGridAod( @ApiParam("ç½æ ¼ç»id") @RequestParam groupId: Int, @ApiParam("饿µæ°æ®æ¶é´") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") dataTime: LocalDateTime?, ) = resPack { satelliteTelemetryService.fetchGridAod(groupId, dataTime) } @ApiOperation(value = "å¯¼å ¥å«æé¥æµAodç»ææ°æ®") @PostMapping("/import/grid/aod") fun importGridAOD( @ApiParam("ç½æ ¼ç»id") @RequestParam groupId: Int, @ApiParam("饿µæ°æ®æ¶é´") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") dateTime: LocalDateTime, @ApiParam("è¦çæ§æ°æ® 0: ä¸è¦ç 1: è¦ç") @RequestParam update: Boolean, @RequestParam("excel") file: MultipartFile, ) = resPack { satelliteTelemetryService.importGridAOD(groupId, dateTime, update, file) } @ApiOperation(value = "ä¸è½½å«æé¥æµAodç»ææ°æ®å¯¼å ¥æ¨¡æ¿") @GetMapping("/import/grid/aod/download/template") fun downloadAODTemplate(@ApiIgnore response: HttpServletResponse) = satelliteTelemetryService.downloadAODTemplate(response) } src/main/resources/mapper/GridAodDetailMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.flightfeather.uav.domain.mapper.GridAodDetailMapper"> <resultMap id="BaseResultMap" type="com.flightfeather.uav.domain.entity.GridAodDetail"> <!-- WARNING - @mbg.generated --> <id column="id" jdbcType="INTEGER" property="id" /> <result column="aod_id" jdbcType="INTEGER" property="aodId" /> <result column="group_id" jdbcType="INTEGER" property="groupId" /> <result column="cell_id" jdbcType="INTEGER" property="cellId" /> <result column="aod" jdbcType="REAL" property="aod" /> </resultMap> <sql id="Base_Column_List"> <!-- WARNING - @mbg.generated --> id, aod_id, group_id, cell_id, aod </sql> </mapper> src/main/resources/mapper/GridAodMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.flightfeather.uav.domain.mapper.GridAodMapper"> <resultMap id="BaseResultMap" type="com.flightfeather.uav.domain.entity.GridAod"> <!-- WARNING - @mbg.generated --> <id column="id" jdbcType="INTEGER" property="id" /> <result column="group_id" jdbcType="INTEGER" property="groupId" /> <result column="data_time" jdbcType="TIMESTAMP" property="dataTime" /> </resultMap> <sql id="Base_Column_List"> <!-- WARNING - @mbg.generated --> id, group_id, data_time </sql> </mapper> src/main/resources/mapper/GridDataDetailMapper.xml
@@ -18,4 +18,15 @@ --> id, data_id, group_id, cell_id, PM25, rank </sql> <!-- æ·»å æ¹éæ´æ°PM25ç彿° --> <update id="updatePM25Batch" parameterType="java.util.List"> <foreach collection="list" item="item" separator=";"> UPDATE grid_data_detail SET PM25 = #{item.pm25} WHERE data_id = #{item.dataId} AND group_id = #{item.groupId} AND cell_id = #{item.cellId} </foreach> </update> </mapper> src/main/resources/templates/GridData-AOD-Template.xlsxBinary files differ
src/main/resources/templates/GridData-PM2.5-Template.xlsxBinary files differ