feiyu02
2024-01-10 30a53b41f09d2eefd33513a409d472c2166ba1ea
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
153
package cn.flightfeather.supervision.business.autooutput.dataanalysis
 
import cn.flightfeather.supervision.business.autooutput.AopOutput
import cn.flightfeather.supervision.business.autooutput.datasource.AopDataSource
import cn.flightfeather.supervision.business.autooutput.datasource.AopDbMapper
import cn.flightfeather.supervision.business.autooutput.datasource.AopSceneTypeCheck
import cn.flightfeather.supervision.domain.ds2.entity.DustSiteMap
import cn.flightfeather.supervision.domain.ds2.entity.HourDustData
import cn.flightfeather.supervision.domain.ds2.mapper.DustSiteMapMapper
import cn.flightfeather.supervision.domain.ds2.mapper.HourDustDataMapper
import org.springframework.stereotype.Component
import tk.mybatis.mapper.entity.Example
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import kotlin.math.round
 
/**
 * 静安工地扬尘监测数据统计
 */
@Component
class JACsDataAnalysis(
    aopDbMapper: AopDbMapper,
    aopSceneTypeCheck: AopSceneTypeCheck,
    aopOutput: AopOutput,
    private val dustSiteMapMapper: DustSiteMapMapper,
    private val hourDustDataMapper: HourDustDataMapper,
) : AopDataAnalysis<HourDustData>(aopDbMapper, aopSceneTypeCheck, aopOutput) {
 
    companion object {
        private const val FLAG_NA = "NA"
        private const val FLAG_N = "N"
        private const val FLAG_I = "I"
    }
 
    override fun districtAvg(source: AopDataSource?): Double? {
        var total = .0
        var count = 0
        hourDustDataMapper.selectByExample(Example(HourDustData::class.java).apply {
            createCriteria().andBetween("lst", source?.config?.startTime, source?.config?.endTime)
                .andEqualTo("flag", "N")
        }).forEach {
            it?.dustvalue?.let { v ->
                total += v
                count++
            }
        }
        return if (count == 0) {
            .0
        } else {
            round((total / count) * 1000) / 1000
        }
    }
 
    override fun fetchDataResources(evaluationScene: AopDataSource.EvaluationScene): List<List<HourDustData?>> {
        val dustSiteMaps = dustSiteMapMapper.selectByExample(Example(DustSiteMap::class.java).apply {
            createCriteria().andEqualTo("svUserId", evaluationScene.userInfo.value?.guid)
                .andIsNotNull("jaMnCode")
        })
        if (dustSiteMaps.isEmpty()) return emptyList()
 
        val mnCodeList =  dustSiteMaps.map { it?.jaMnCode }
        val map = mutableMapOf<String?, MutableList<HourDustData?>>()
        hourDustDataMapper.selectByExample(Example(HourDustData::class.java).apply {
            createCriteria().andBetween("lst", evaluationScene.config?.startTime, evaluationScene.config?.endTime)
                .andIn("mncode", mnCodeList)
        }).forEach {
            if (!map.containsKey(it?.mncode)) {
                map[it?.mncode] = mutableListOf()
            }
            map[it?.mncode]?.add(it)
        }
        val res = mutableListOf<List<HourDustData?>>()
        map.forEach { (_, u) ->
            res.add(u)
        }
        return res
    }
 
    override fun exceedTimes(data: HourDustData, t: TempResult) {
        data.dustvalue?.let {
            if (it >= 1) {
                t.count++
            }
        }
    }
 
    override fun avg(data: HourDustData, t: TempResult) {
        // 补传的不计算
        if (data.flag == FLAG_NA) return
 
        data.dustvalue?.let {
            t.total += it
            t.count++
        }
    }
 
    override fun max(data: HourDustData, t: TempResult) {
        data.dustvalue?.let {
            if (it > t.total) {
                t.total = it
            }
        }
    }
 
    override fun min(data: HourDustData, t: TempResult) {
        // 补传的不计算
        if (data.flag == FLAG_NA) return
 
        data.dustvalue?.let {
            if (t.count == 0 || it < t.total) {
                t.total = it
            }
            // 通过t.count 来判定是否是初始化状态
            if (t.count == 0) t.count = 1
        }
    }
 
    override fun overAvgRate(avg: Double, dAvg: Double?): Double? {
        return if (dAvg != null) {
            round(((avg - dAvg) / dAvg) * 1000) / 1000
        } else {
            null
        }
    }
 
    override fun count(dataList: List<List<HourDustData?>>): Int {
        var count = 0
        dataList.forEach {
            it.forEach {h ->
                if (h?.flag != FLAG_NA) {
                    count ++
                }
            }
        }
        return count
    }
 
    override fun effectiveRate(dataList: List<List<HourDustData?>>, evaluationScene: AopDataSource.EvaluationScene):
            Double {
        if (dataList.isEmpty()) return .0
 
        val st = LocalDateTime.ofInstant(evaluationScene.config?.startTime?.toInstant(), ZoneId.systemDefault())
        val et = LocalDateTime.ofInstant(evaluationScene.config?.endTime?.toInstant(), ZoneId.systemDefault())
        val days = Duration.between(st, et).toDays() + 1
 
        return if (days == 0L) {
            .0
        } else {
            round((count(dataList) / (dataList.size * days * 24).toDouble()) * 1000) / 1000
        }
    }
}