1. 新增走航任务增删改查相关功能
2. 新增无人船数据excel导入功能
3. 优化多参数接收逻辑,解决单个数据头导致数据包结构判断错误问题
已修改7个文件
已添加7个文件
342 ■■■■■ 文件已修改
src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/entity/Mission.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/mapper/MissionMapper.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataImportResult.kt 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/MissionService.kt 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/RealTimeDataService.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/web/MissionController.kt 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/web/RealTimeDataController.kt 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/socket/UAVByteDataDecoder.kt 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/generator/generatorConfig.xml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/MissionMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/common/utils/FileExchange.kt
@@ -1,11 +1,13 @@
package com.flightfeather.uav.common.utils
import com.alibaba.fastjson.JSONObject
import com.flightfeather.uav.domain.entity.RealTimeData
import com.flightfeather.uav.socket.bean.AirData
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.*
@@ -21,6 +23,79 @@
        private val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    }
    fun exchangeBoatData(deviceCode: String, file: InputStream): List<RealTimeData> {
        val workbook = HSSFWorkbook(file)
        val sheet = workbook.getSheetAt(0)
        val dataList = mutableListOf<RealTimeData>()
        for (i in 1 until sheet.lastRowNum) {
            val row = sheet.getRow(i)
            val time = row.getCell(2).numericCellValue.toLong() * 1000
            val lat = row.getCell(4).numericCellValue
            val lng = row.getCell(5).numericCellValue
            val value = row.getCell(6).stringCellValue
            //时间
            val datetime = Date(time)
            //监测因子
            val jO = JSONObject.parseObject(value)
            val tmp = jO.getDoubleValue(TMP)
            val spC = jO.getDoubleValue(SPCOND)
            val tur = jO.getDoubleValue(TUR)
            val dO = jO.getDoubleValue(DO)
            val ph = jO.getDoubleValue(PH)
            val factorsList = mutableListOf<AirData>()
            factorsList.apply {
                add(AirData().apply {
                    factorId = "1"
                    factorName = "TMP"
                    factorData = tmp
                    physicalQuantity = 0.0
                })
                add(AirData().apply {
                    factorId = "2"
                    factorName = "spC"
                    factorData = spC
                    physicalQuantity = 0.0
                })
                add(AirData().apply {
                    factorId = "3"
                    factorName = "tur"
                    factorData = tur
                    physicalQuantity = 0.0
                })
                add(AirData().apply {
                    factorId = "4"
                    factorName = "DO"
                    factorData = dO
                    physicalQuantity = 0.0
                })
                add(AirData().apply {
                    factorId = "5"
                    factorName = "PH"
                    factorData = ph
                    physicalQuantity = 0.0
                })
            }
            val factors = JSONObject.toJSON(factorsList).toString()
            dataList.add(RealTimeData().apply {
                this.deviceCode = deviceCode
                latitude = lat.toBigDecimal()
                longitude = lng.toBigDecimal()
                dataTime = datetime
                createTime = Date()
                this.factors = factors
            })
        }
        return dataList
    }
    fun doTask() {
        //source
        val path = "E:\\工作\\金山走航\\MissionData.xls"
src/main/kotlin/com/flightfeather/uav/domain/entity/Mission.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.flightfeather.uav.domain.entity;
import java.util.Date;
import javax.persistence.*;
public class Mission {
    @Id
    @Column(name = "mission_code")
    private String missionCode;
    @Column(name = "device_type")
    private String deviceType;
    @Column(name = "device_code")
    private String deviceCode;
    @Column(name = "start_time")
    private Date startTime;
    @Column(name = "end_time")
    private Date endTime;
    /**
     * @return mission_code
     */
    public String getMissionCode() {
        return missionCode;
    }
    /**
     * @param missionCode
     */
    public void setMissionCode(String missionCode) {
        this.missionCode = missionCode == null ? null : missionCode.trim();
    }
    /**
     * @return device_type
     */
    public String getDeviceType() {
        return deviceType;
    }
    /**
     * @param deviceType
     */
    public void setDeviceType(String deviceType) {
        this.deviceType = deviceType == null ? null : deviceType.trim();
    }
    /**
     * @return device_code
     */
    public String getDeviceCode() {
        return deviceCode;
    }
    /**
     * @param deviceCode
     */
    public void setDeviceCode(String deviceCode) {
        this.deviceCode = deviceCode == null ? null : deviceCode.trim();
    }
    /**
     * @return start_time
     */
    public Date getStartTime() {
        return startTime;
    }
    /**
     * @param startTime
     */
    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
    /**
     * @return end_time
     */
    public Date getEndTime() {
        return endTime;
    }
    /**
     * @param endTime
     */
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }
}
src/main/kotlin/com/flightfeather/uav/domain/mapper/MissionMapper.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.flightfeather.uav.domain.mapper
import com.flightfeather.uav.domain.MyMapper
import com.flightfeather.uav.domain.entity.Mission
import org.apache.ibatis.annotations.Mapper
@Mapper
interface MissionMapper : MyMapper<Mission?>
src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataImportResult.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.flightfeather.uav.lightshare.bean
import com.fasterxml.jackson.annotation.JsonInclude
/**
 * ç›‘测数据导入处理结果
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
data class DataImportResult(
    val result: String
)
src/main/kotlin/com/flightfeather/uav/lightshare/service/MissionService.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.flightfeather.uav.lightshare.service
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.lightshare.bean.BaseResponse
interface MissionService {
    fun getMission(type: String?, page: Int?, perPage: Int?): BaseResponse<List<Mission>>
    fun createMission(mission: Mission): BaseResponse<Boolean>
    fun deleteMission(missionCode: String): BaseResponse<Boolean>
}
src/main/kotlin/com/flightfeather/uav/lightshare/service/RealTimeDataService.kt
@@ -1,11 +1,15 @@
package com.flightfeather.uav.lightshare.service
import com.flightfeather.uav.lightshare.bean.BaseResponse
import com.flightfeather.uav.lightshare.bean.DataImportResult
import com.flightfeather.uav.lightshare.bean.DataVo
import org.springframework.web.multipart.MultipartFile
interface RealTimeDataService {
    fun getSecondData(deviceCode: String?, startTime: String?, endTime: String?, page: Int?, perPage: Int?): BaseResponse<List<DataVo>>
    fun getNextData(deviceCode: String, updateTime: String, page: Int?, perPage: Int?): BaseResponse<List<DataVo>>
    fun importData(file: MultipartFile): BaseResponse<DataImportResult>
}
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.flightfeather.uav.lightshare.service.impl
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.domain.mapper.MissionMapper
import com.flightfeather.uav.lightshare.bean.BaseResponse
import com.flightfeather.uav.lightshare.bean.DataHead
import com.flightfeather.uav.lightshare.service.MissionService
import com.github.pagehelper.PageHelper
import org.springframework.stereotype.Service
import tk.mybatis.mapper.entity.Example
@Service
class MissionServiceImpl(private val missionMapper: MissionMapper) : MissionService {
    override fun getMission(type: String?, page: Int?, perPage: Int?): BaseResponse<List<Mission>> {
        val _perPage = perPage ?: 60
        val _page = page ?: 1
        val pageInfo = PageHelper.startPage<Mission>(_page, _perPage)
        val result = mutableListOf<Mission>()
        missionMapper.selectByExample(Example(Mission::class.java).apply {
            type?.let {
                createCriteria().andEqualTo("deviceType", type)
            }
            orderBy("startTime").desc()
        }).forEach { it?.let { result.add(it) } }
        return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages),data = result)
    }
    override fun createMission(mission: Mission): BaseResponse<Boolean> {
        missionMapper.selectByPrimaryKey(mission.missionCode)?.run {
            return BaseResponse(false, "任务编号已存在")
        }
        missionMapper.insert(mission).let {
            return BaseResponse(it == 1)
        }
    }
    override fun deleteMission(missionCode: String): BaseResponse<Boolean> {
        missionMapper.deleteByPrimaryKey(missionCode).let {
            return BaseResponse(it == 1)
        }
    }
}
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt
@@ -1,16 +1,22 @@
package com.flightfeather.uav.lightshare.service.impl
import com.flightfeather.uav.common.utils.FileExchange
import com.flightfeather.uav.common.utils.GsonUtils
import com.flightfeather.uav.domain.entity.RealTimeData
import com.flightfeather.uav.domain.mapper.RealTimeDataMapper
import com.flightfeather.uav.lightshare.bean.BaseResponse
import com.flightfeather.uav.lightshare.bean.DataHead
import com.flightfeather.uav.lightshare.bean.DataImportResult
import com.flightfeather.uav.lightshare.bean.DataVo
import com.flightfeather.uav.lightshare.service.RealTimeDataService
import com.flightfeather.uav.socket.bean.AirData
import com.github.pagehelper.PageHelper
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import tk.mybatis.mapper.entity.Example
import java.io.ByteArrayInputStream
import java.io.FileInputStream
import java.io.InputStream
import java.text.DateFormat
import java.text.SimpleDateFormat
@@ -18,6 +24,7 @@
class RealTimeDataServiceImpl(val realTimeDataMapper: RealTimeDataMapper) : RealTimeDataService {
    private var dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    private val fileExchange = FileExchange()
    override fun getSecondData(deviceCode: String?, startTime: String?, endTime: String?, page: Int?, perPage: Int?): BaseResponse<List<DataVo>> {
        val _perPage = perPage ?: 60
@@ -71,4 +78,12 @@
        }
        return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result)
    }
    override fun importData(file: MultipartFile): BaseResponse<DataImportResult> {
        val f = ByteArrayInputStream(file.bytes)
        fileExchange.exchangeBoatData("0c0000000001", f).forEach {
            realTimeDataMapper.insert(it)
        }
        return BaseResponse(true, data = DataImportResult(""))
    }
}
src/main/kotlin/com/flightfeather/uav/lightshare/web/MissionController.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.flightfeather.uav.lightshare.web
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.lightshare.service.MissionService
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("air/mission")
class MissionController(private val missionService: MissionService) {
    @GetMapping("/type")
    fun getMission(
        @RequestParam(value = "type", required = false) type: String?,
        @RequestParam(value = "page", required = false) page: Int?,
        @RequestParam(value = "perPage", required = false) perPage: Int?
    ) = missionService.getMission(type, page, perPage)
    @PostMapping("/create")
    fun createMission(
        @RequestBody mission: Mission
    ) = missionService.createMission(mission)
    @PostMapping("/delete")
    fun deleteMission(
        @RequestParam("missionCode") missionCode: String
    ) = missionService.deleteMission(missionCode)
}
src/main/kotlin/com/flightfeather/uav/lightshare/web/RealTimeDataController.kt
@@ -1,10 +1,8 @@
package com.flightfeather.uav.lightshare.web
import com.flightfeather.uav.lightshare.service.RealTimeDataService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
@RestController
@RequestMapping("air/realtime")
@@ -26,4 +24,9 @@
        @RequestParam(value = "page", required = false) page: Int?,
        @RequestParam(value = "perPage", required = false) perPage: Int?
    ) = realTimeDataService.getNextData(deviceCode, updateTime, page, perPage)
    @PostMapping("/import")
    fun importData(
        @RequestPart("excel") file: MultipartFile
    ) = realTimeDataService.importData(file)
}
src/main/kotlin/com/flightfeather/uav/socket/UAVByteDataDecoder.kt
@@ -17,6 +17,8 @@
        const val BASE_LENGTH = DataPackageDecoderImpl.HEAD_BYTES + DataPackageDecoderImpl.COMMAND_UNIT_BYTES +
                DataPackageDecoderImpl.DEVICE_CODE_BYTES + DataPackageDecoderImpl.DATA_LENGTH + DataPackageDecoderImpl.BCC_BYTES
        const val HEAD1 = 0x01.toByte()
        const val COMMAND_1 = 0x01.toByte()
        const val COMMAND_2 = 0x01.toByte()
        const val HEAD_LENGTH = DataPackageDecoderImpl.HEAD_BYTES + DataPackageDecoderImpl.COMMAND_UNIT_BYTES +
                DataPackageDecoderImpl.DEVICE_CODE_BYTES
    }
@@ -44,7 +46,8 @@
                    // è¯»åˆ°äº†åè®®çš„开始标志,结束while循环
                    val b = ByteArray(HEAD_LENGTH)
                    it.readBytes(b)
                    if (b[0] == HEAD1) {
                    if (b[0] == HEAD1 &&
                        (b[1] == COMMAND_1 || b[2] == COMMAND_2)) {
                        b.forEach {b ->
                            dataList.add(b)
                        }
src/main/resources/application.yml
@@ -16,6 +16,11 @@
  jmx:
    enabled: false
  #文件上传限制
  servlet:
    multipart:
      max-file-size: 25MB
      max-request-size: 100MB
mybatis:
src/main/resources/generator/generatorConfig.xml
@@ -24,7 +24,7 @@
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库链接URL,用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://114.215.109.124:3306/dronemonitor"
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/dronemonitor"
                        userId="root"
                        password="123456">
        </jdbcConnection>
@@ -45,15 +45,7 @@
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- è¦ç”Ÿæˆçš„表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
        <!--<table tableName="obd_data" domainObjectName="ObdData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_user" domainObjectName="ObdUser" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_threshold_value" domainObjectName="ThresholdValue" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_alarm_data" domainObjectName="AlarmData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_origin_data" domainObjectName="OriginData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_car_login" domainObjectName="CarLogin" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_car_logout" domainObjectName="CarLogout" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_data_stream" domainObjectName="DataStream" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <!--<table tableName="obd_info" domainObjectName="ObdInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="air_real_time_data" domainObjectName="RealTimeData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
<!--        <table tableName="air_real_time_data" domainObjectName="RealTimeData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="mission" domainObjectName="Mission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>
src/main/resources/mapper/MissionMapper.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.MissionMapper">
  <resultMap id="BaseResultMap" type="com.flightfeather.uav.domain.entity.Mission">
    <!--
      WARNING - @mbg.generated
    -->
    <id column="mission_code" jdbcType="VARCHAR" property="missionCode" />
    <result column="device_type" jdbcType="VARCHAR" property="deviceType" />
    <result column="device_code" jdbcType="VARCHAR" property="deviceCode" />
    <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
    <result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--
      WARNING - @mbg.generated
    -->
    mission_code, device_type, device_code, start_time, end_time
  </sql>
</mapper>