From b7b520bfe8b35683112284861f0dca8e645cbd56 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期二, 31 十二月 2024 10:22:40 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/hc-satellite-data-import-1227_2' --- src/main/kotlin/com/flightfeather/uav/lightshare/bean/GridDataImportResult.kt | 12 + src/main/resources/mapper/GridAodMapper.xml | 18 + src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt | 193 ++++++++++++++++ src/main/resources/mapper/GridAodDetailMapper.xml | 20 + src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodDetailMapper.kt | 8 src/main/kotlin/com/flightfeather/uav/domain/entity/GridData.java | 1 src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt | 61 ++++ src/main/resources/templates/GridData-AOD-Template.xlsx | 0 src/main/kotlin/com/flightfeather/uav/domain/entity/GridAod.java | 59 ++++ src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt | 141 +++++++++++ src/main/resources/templates/GridData-PM2.5-Template.xlsx | 0 src/main/kotlin/com/flightfeather/uav/domain/entity/GridAodDetail.java | 92 +++++++ src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodMapper.kt | 8 src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt | 17 + src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt | 47 +++ src/main/kotlin/com/flightfeather/uav/domain/mapper/GridDataDetailMapper.kt | 4 src/main/resources/mapper/GridDataDetailMapper.xml | 11 17 files changed, 685 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt index ea62b09..423644f 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt +++ b/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> { + // 妯′豢宸叉湁浠g爜鍒ゆ柇琛ㄥご姝g‘鎬� 骞跺湪閿欒鏃舵姏鍑哄紓甯� + 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 + // 寰楀埌褰撳墠鍗曞厓鏍肩殑瀹氫綅淇℃伅 锛坋g: B3,BA3...锛� + val cellIdCellPosStr = CellAddress(it.rowNum, 0).formatAsString() + // 寰楀埌褰撳墠鍗曞厓鏍兼暟鎹被鍨� + val cellIdCellType = it.getCell(0).cellType + when (cellIdCellType) { + CellType.NUMERIC -> { + // 褰撳�间负鏁板瓧绫诲瀷鏃惰浆鍖栦负缃戞牸鍗曞厓鏍糹d + this.cellId = it.getCell(0)?.numericCellValue?.toInt() + } + else -> { + throw BizException("鍗曞厓鏍糩${cellIdCellPosStr}]涓嶆槸鏁板瓧绫诲瀷") + } + } + + // 杞崲PM2.5 + // 寰楀埌褰撳墠鍗曞厓鏍肩殑瀹氫綅淇℃伅 锛坋g: 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 + } + // 鍒ゆ柇缃戞牸鍗曞厓鏍肩紪鍙锋槸鍚﹀湪姝g‘鐨勮寖鍥村唴 + 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> { + // 妯′豢宸叉湁浠g爜鍒ゆ柇琛ㄥご姝g‘鎬� 骞跺湪閿欒鏃舵姏鍑哄紓甯� + 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 + // 寰楀埌褰撳墠鍗曞厓鏍肩殑瀹氫綅淇℃伅 锛坋g: B3,BA3...锛� + val cellIdCellPosStr = CellAddress(it.rowNum, 0).formatAsString() + // 寰楀埌褰撳墠鍗曞厓鏍兼暟鎹被鍨� + val cellIdCellType = it.getCell(0).cellType + when (cellIdCellType) { + CellType.NUMERIC -> { + // 褰撳�间负鏁板瓧绫诲瀷鏃惰浆鍖栦负缃戞牸鍗曞厓鏍糹d + this.cellId = it.getCell(0)?.numericCellValue?.toInt() + } + else -> { + throw BizException("鍗曞厓鏍糩${cellIdCellPosStr}]涓嶆槸鏁板瓧绫诲瀷") + } + } + + // 杞崲AOD + // 寰楀埌褰撳墠鍗曞厓鏍肩殑瀹氫綅淇℃伅 锛坋g: 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 + } + // 鍒ゆ柇缃戞牸鍗曞厓鏍肩紪鍙锋槸鍚﹀湪姝g‘鐨勮寖鍥村唴 + 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> { diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/GridAod.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/GridAod.java new file mode 100644 index 0000000..de6d5de --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/GridAodDetail.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/GridAodDetail.java new file mode 100644 index 0000000..15b16ad --- /dev/null +++ b/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; + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/GridData.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/GridData.java index e008649..2273b64 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/entity/GridData.java +++ b/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; /** diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodDetailMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodDetailMapper.kt new file mode 100644 index 0000000..4576917 --- /dev/null +++ b/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?> \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridAodMapper.kt new file mode 100644 index 0000000..73b0da3 --- /dev/null +++ b/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?> \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridDataDetailMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridDataDetailMapper.kt index 1a6f152..cf4437e 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/mapper/GridDataDetailMapper.kt +++ b/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?> \ No newline at end of file +interface GridDataDetailMapper : MyMapper<GridDataDetail?> { + fun updatePM25Batch(gridDataDetails: List<GridDataDetail>) +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt index 2c0db63..b88bc35 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt +++ b/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) + }) + } + + } + } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/GridDataImportResult.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/GridDataImportResult.kt new file mode 100644 index 0000000..7afad90 --- /dev/null +++ b/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 +) \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt index 8263119..97014cb 100644 --- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt +++ b/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 } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt index 60ef723..db1be82 100644 --- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt +++ b/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 + // 棣栧厛鍒ゆ柇鏂囦欢绫诲瀷锛屾枃浠剁被鍨嬩笉鏄痻lsx鐩存帴鎶ラ敊 + 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? { + // 棣栧厛鍒ゆ柇鏂囦欢绫诲瀷锛屾枃浠剁被鍨嬩笉鏄痻lsx鐩存帴鎶ラ敊 + 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 + } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt index 2ac67d6..f5b6175 100644 --- a/src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt +++ b/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("缃戞牸缁刬d") @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("缃戞牸缁刬d") @RequestParam(required = false) groupId: Int?, @ApiParam("缃戞牸鍗曞厓鏍糹d") @RequestParam(required = false) cellId: Int?, ) = resPack { satelliteTelemetryService.fetchGridDataDetail(dataId, groupId, cellId) } + + + @ApiOperation(value = "瀵煎叆鍗槦閬ユ祴PM2.5缁撴灉鏁版嵁") + @PostMapping("/import/grid/data") + fun importGridData( + @ApiParam("缃戞牸缁刬d") @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 = "鑾峰彇缃戞牸缁勪笅鐨勫崼鏄熼仴娴媋od鏁版嵁") + @GetMapping("/grid/aod") + fun fetchGridAod( + @ApiParam("缃戞牸缁刬d") @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("缃戞牸缁刬d") @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) } \ No newline at end of file diff --git a/src/main/resources/mapper/GridAodDetailMapper.xml b/src/main/resources/mapper/GridAodDetailMapper.xml new file mode 100644 index 0000000..c860a3f --- /dev/null +++ b/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> \ No newline at end of file diff --git a/src/main/resources/mapper/GridAodMapper.xml b/src/main/resources/mapper/GridAodMapper.xml new file mode 100644 index 0000000..48fb717 --- /dev/null +++ b/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> \ No newline at end of file diff --git a/src/main/resources/mapper/GridDataDetailMapper.xml b/src/main/resources/mapper/GridDataDetailMapper.xml index 6312fe3..7574d75 100644 --- a/src/main/resources/mapper/GridDataDetailMapper.xml +++ b/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> \ No newline at end of file diff --git a/src/main/resources/templates/GridData-AOD-Template.xlsx b/src/main/resources/templates/GridData-AOD-Template.xlsx new file mode 100644 index 0000000..e75b413 --- /dev/null +++ b/src/main/resources/templates/GridData-AOD-Template.xlsx Binary files differ diff --git a/src/main/resources/templates/GridData-PM2.5-Template.xlsx b/src/main/resources/templates/GridData-PM2.5-Template.xlsx new file mode 100644 index 0000000..26054f7 --- /dev/null +++ b/src/main/resources/templates/GridData-PM2.5-Template.xlsx Binary files differ -- Gitblit v1.9.3