1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package com.flightfeather.uav.lightshare.service.impl
 
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.common.utils.ExcelUtil
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.entity.toRowContent
import com.flightfeather.uav.domain.entity.toRowTitle
import com.flightfeather.uav.domain.mapper.RealTimeDataMapper
import com.flightfeather.uav.lightshare.bean.*
import com.flightfeather.uav.lightshare.service.RealTimeDataService
import com.flightfeather.uav.socket.bean.AirData
import com.github.pagehelper.PageHelper
import org.apache.poi.xssf.streaming.SXSSFWorkbook
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import tk.mybatis.mapper.entity.Example
import java.io.ByteArrayInputStream
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletResponse
 
@Service
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
        val _page = page ?: 1
        val sTime = startTime?.let { dateFormatter.parse(it) }
        val eTime = endTime?.let { dateFormatter.parse(it) }
        val pageInfo = PageHelper.startPage<RealTimeData>(_page, _perPage)
        val result = mutableListOf<DataVo>()
        realTimeDataMapper.selectByExample(Example(RealTimeData::class.java).apply {
            createCriteria().apply {
                deviceCode?.let { andEqualTo("deviceCode", it) }
                sTime?.let { andGreaterThanOrEqualTo("dataTime", it) }
                eTime?.let { andLessThanOrEqualTo("dataTime", it) }
            }
            orderBy("dataTime").apply {
                // 当请求接口不传递起始时间,默认获取最新的数据
                if (startTime == null && endTime == null) {
                    desc()
                }
            }
        }).forEach {
            if (it.longitude == null || it.latitude == null) {
                return@forEach
            }
            result.add(DataVo(
                    dateFormatter.format(it.dataTime),
                    it.deviceCode,
                    GsonUtils.parserJsonToArrayBeans(it.factors, AirData::class.java),
                    it.longitude?.toDouble(), it.latitude?.toDouble()
            ))
        }
        if (startTime == null && endTime == null) {
            result.reverse()
        }
        return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result)
    }
 
    override fun getNextData(deviceCode: String, updateTime: String, page: Int?, perPage: Int?): BaseResponse<List<DataVo>> {
        val _perPage = perPage ?: 60
        val _page = page ?: 1
        val pageInfo = PageHelper.startPage<RealTimeData>(_page, _perPage)
        val result = mutableListOf<DataVo>()
        realTimeDataMapper.selectByExample(Example(RealTimeData::class.java).apply {
            createCriteria().andEqualTo("deviceCode", deviceCode)
                .andGreaterThan("dataTime", updateTime)
            orderBy("dataTime")
        }).forEach {
            result.add(DataVo(
                dateFormatter.format(it.dataTime),
                it.deviceCode,
                GsonUtils.parserJsonToArrayBeans(it.factors, AirData::class.java),
                it.longitude.toDouble(), it.latitude.toDouble()
            ))
        }
        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(""))
    }
 
    override fun outToWorkbook(deviceCode: String, startTime: String, endTime: String): SXSSFWorkbook {
        val sTime = dateFormatter.parse(startTime)
        val eTime = dateFormatter.parse(endTime)
        var page = 1
        var totalPage = 1
        val pageSize = 10000
        val workbook = SXSSFWorkbook()
        var rowIndex = 0
        while (page <= totalPage) {
            val pageInfo = PageHelper.startPage<RealTimeData>(page, pageSize)
            val r = realTimeDataMapper.selectByExample(Example(RealTimeData::class.java).apply {
                createCriteria().andEqualTo("deviceCode", deviceCode)
                    .apply {
                        sTime?.let { andGreaterThanOrEqualTo("dataTime", it) }
                        eTime?.let { andLessThanOrEqualTo("dataTime", it) }
                    }
            })
            if (r.isNotEmpty()) {
                val heads = if (page == 1) {
                    println("[${DateUtil.instance.dateToString(Date(), DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)}] totalPage: ${pageInfo.pages}")
                    getTableTitle(r[0])
                } else {
                    emptyList()
                }
                val contents = getTableContents(r)
                print("[${DateUtil.instance.dateToString(Date(), DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)}] currentPage: ${pageInfo.pageNum}......")
                rowIndex = ExcelUtil.write(heads, contents, workbook, row = rowIndex)
                println("output done")
            }
            totalPage = pageInfo.pages
            page++
        }
        return workbook
    }
 
    override fun outToExcel(deviceCode: String, startTime: String, endTime: String, response: HttpServletResponse): HttpServletResponse {
        val workbook = outToWorkbook(deviceCode, startTime, endTime)
 
        val out = response.outputStream
        workbook.write(out)
        workbook.close()
        out.flush()
        out.close()
 
        return response
    }
 
    fun getTableTitle(d: RealTimeData): List<Array<String>> {
        return listOf(d.toRowTitle())
    }
 
    fun getTableContents(list: List<RealTimeData>): List<Array<Any>> {
        val contents = mutableListOf<Array<Any>>()
        list.forEach {
            contents.add(it.toRowContent())
        }
        return contents
    }
}