feiyu02
2023-10-24 70a7d1ec98064e1acb3130e56e16c45af52ade6c
新增数据分析模块完成
已修改16个文件
已删除3个文件
已添加18个文件
已重命名4个文件
985 ■■■■■ 文件已修改
pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/MonitorApplication.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/ServletInitializer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/AnalysisController.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/BaseDustExceptionAnalysis.kt 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/BaseExceptionContinuous.kt 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionAnalysisController.kt 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataExceed.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataLowValue.kt 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataMissing.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionExceedingTimes.kt 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionSlideAverage.kt 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionValueMutation.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/analysis/dust/StatisticAnalysisController.kt 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/entity/DustExceptionSetting.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/entity/DustSiteStatus.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustSiteLatestTimeMapper.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustSiteStatusMapper.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustStatisticsValueMapper.kt 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionDataRep.kt 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionSettingRep.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustSiteDataRep.kt 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustSiteStatusRep.kt 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustStatisticsValueRep.kt 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/enumration/dust/DeviceStatus.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/enumration/dust/ExceptionType.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/BaseTimingTask.kt 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/DustDailyStatisticAnalysisTask.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/DustExceptionAnalysisTask.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/DustMonthlyStatisticAnalysisTask.kt 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/ScheduledTaskController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/scheduledtasks/TaskController.kt 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/flightfeather/monitor/utils/DateUtil.kt 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/generator/generatorConfig4ds1.xml 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/DustExceptionSettingMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/DustSiteStatusMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/DustStatisticsValueMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/flightfeather/monitor/MonitorApplicationTests.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/flightfeather/monitor/analysis/dust/ExceptionAnalysisControllerTest.kt 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/flightfeather/monitor/analysis/dust/StatisticAnalysisControllerTest.kt 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -91,6 +91,11 @@
            <artifactId>commons-codec</artifactId>
            <version>1.14</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
src/main/java/com/flightfeather/monitor/MonitorApplication.java
ÎļþÃû´Ó src/main/java/com/flightfeather/monitor/QianduanApplication.java ÐÞ¸Ä
@@ -8,7 +8,7 @@
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class QianduanApplication {
public class MonitorApplication {
    @Autowired
    private TaskController taskController;
@@ -16,8 +16,9 @@
    public ApplicationRunner runner() {
         return args -> taskController.run();
    }
    public static void main(String[] args) {
        SpringApplication.run(QianduanApplication.class, args);
        SpringApplication.run(MonitorApplication.class, args);
    }
src/main/java/com/flightfeather/monitor/ServletInitializer.java
@@ -7,6 +7,6 @@
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(QianduanApplication.class);
        return builder.sources(MonitorApplication.class);
    }
}
src/main/java/com/flightfeather/monitor/analysis/AnalysisController.kt
ÎļþÒÑɾ³ý
src/main/java/com/flightfeather/monitor/analysis/dust/BaseDustExceptionAnalysis.kt
@@ -32,15 +32,15 @@
    /**
     * ç”Ÿæˆä¸€æ¡å¼‚常分析结果
     */
    protected fun newResult(p: DustSiteData?, n: DustSiteData): DustExceptionData {
    open fun newResult(p: DustSiteData, n: DustSiteData?): DustExceptionData {
        val eType = getExceptionType()
        return DustExceptionData().apply {
            mnCode = n.mnCode
            mnCode = p.mnCode
            exception = eType.des
            exceptionType = eType.value
            region = config.region
            beginTime = if (p == null) n.lst else p.lst
            endTime = n.lst
            beginTime = p.lst
            endTime = if (n == null) p.lst else n.lst
        }
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/BaseExceptionContinuous.kt
@@ -8,10 +8,17 @@
 */
abstract class BaseExceptionContinuous(config: DustExceptionSetting) : BaseDustExceptionAnalysis(config) {
    // èµ·å§‹æ•°æ®ä¸‹æ ‡
    private var sIndex = 0
    // èµ·å§‹æ•°æ®å¯¹è±¡
    private var startData: DustSiteData? = null
    // æœ«å°¾æ•°æ®ä¸‹æ ‡
    private var eIndex = -1
    // æœ«å°¾æ•°æ®å¯¹è±¡
    private var lastData: DustSiteData? = null
    // èµ·å§‹æ•°æ®ä¸Žæœ«å°¾æ•°æ®é—´éš”
    open var durationCount = 1
    private var existException = false
    /**
     * åˆ¤æ–­æ˜¯å¦æ»¡è¶³å¼‚常条件
@@ -24,10 +31,12 @@
    abstract fun judgeDuration(sIndex: Int, eIndex: Int): Boolean
    override fun init() {
        super.init()
        startData = null
        lastData = null
        sIndex = 0
        eIndex = -1
        existException = false
    }
    override fun onNextData(data: DustSiteData) {
@@ -36,11 +45,26 @@
            startData = data
        }
        // åˆ¤æ–­ç›¸é‚»æ•°æ®æ˜¯å¦è¿žç»­å¹¶ä¸”是否满足异常判断
        if (!(isContinuous(lastData, data) && judgeException(lastData, data))) {
        if (!isContinuous(lastData, data)) {
            checkResult()
            sIndex = eIndex
            startData = data
            if (eIndex - sIndex >= durationCount) {
                sIndex = eIndex
                startData = data
            }
        } else {
            if (judgeException(lastData, data)) {
                existException = true
            } else {
                checkResult()
                if (eIndex - sIndex >= durationCount) {
                    sIndex = eIndex
                    startData = data
                }
            }
        }
//        if (!(isContinuous(lastData, data) && judgeException(lastData, data))) {
//
//        }
        lastData = data
    }
@@ -52,8 +76,11 @@
     * æ£€æŸ¥è¿žç»­å¼‚常结束时,是否符合异常存储条件
     */
    private fun checkResult() {
        if (judgeDuration(sIndex, eIndex)) {
            resultList.add(newResult(lastData, startData!!))
        if (existException && judgeDuration(sIndex, eIndex)) {
            startData?.let {
                resultList.add(newResult(it, lastData))
            }
            existException = false
        }
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionAnalysisController.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package com.flightfeather.monitor.analysis.dust
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionData
import com.flightfeather.monitor.domain.ds1.repository.DustExceptionDataRep
import com.flightfeather.monitor.domain.ds1.repository.DustExceptionSettingRep
import com.flightfeather.monitor.domain.ds1.repository.DustSiteDataRep
import com.flightfeather.monitor.domain.ds1.repository.DustSiteStatusRep
import com.flightfeather.monitor.enumration.dust.DeviceStatus
import com.flightfeather.monitor.utils.DateUtil
import org.springframework.stereotype.Component
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
/**
 * æ•°æ®å¼‚常分析控制器
 */
@Component
class ExceptionAnalysisController(
    private val dustExceptionDataRep: DustExceptionDataRep,
    private val dustExceptionSettingRep: DustExceptionSettingRep,
    private val dustSiteDataRep: DustSiteDataRep,
    private val dustSiteStatusRep: DustSiteStatusRep,
) {
    private var running = false
    private val taskList = mutableListOf<BaseDustExceptionAnalysis>()
    fun init() {
        dustExceptionSettingRep.findLatestSetting("金山区")?.let {
            taskList.clear()
            taskList.apply {
                add(ExceptionDataMissing(it))
                add(ExceptionNoFluctuation(it))
                add(ExceptionApproachExceeding(it))
                add(ExceptionExceedingTimes(it))
                add(ExceptionSlideAverage(it))
                add(ExceptionValueMutation(it))
                add(ExceptionDataLowValue(it))
                add(ExceptionDataExceed(it))
            }
        }
    }
    /**
     * è‡ªåŠ¨è¿è¡Œæ—¶çš„å¤„ç†é€»è¾‘
     * åˆ†æžæ˜¨å¤©çš„æ•°æ®
     */
    fun autoRun() {
        val data = dustExceptionDataRep.findLatestData()
        val yesterday = LocalDate.now().minusDays(1)
        if (data == null) {
            // FIXME: 2023/10/23 åº”该是将所有数据进行统计
            run(yesterday)
        } else {
            val date = LocalDateTime.ofInstant(data.endTime.toInstant(), ZoneId.systemDefault())
            val sT = if (date.hour == 0 && date.minute == 0 && date.second == 0) {
                date.toLocalDate()
            } else {
                date.plusDays(1).toLocalDate()
            }
            val du = DateUtil.findDurationDate(sT, yesterday)
            du.forEach {
                run(it)
            }
        }
    }
    fun run(date: LocalDate) {
        running = true
        // åˆ¤æ–­å¯¹åº”日期的异常分析是否存在
//        if (dustExceptionDataRep.findDataExist(date)) return
        // èŽ·å–æ‰€æœ‰å½“å‰ä¸Šçº¿çš„è®¾å¤‡
        val result = mutableListOf<DustExceptionData>()
        dustSiteStatusRep.select(listOf(DeviceStatus.ONLINE, DeviceStatus.STOP)).forEach { s ->
            s?.let {
                taskList.forEach { it.init() }
                // è½®è¯¢æ•°æ®ï¼Œè®¡ç®—各个异常
                dustSiteDataRep.select(s.mnCode, date).takeIf { it.isNotEmpty() }?.forEach {d ->
                    d?.let { taskList.forEach { it.onNextData(d) } }
                }
                // å„个异常分析分别结束
                taskList.forEach { it.onDone() }
                // å­˜å‚¨åˆ†æžç»“æžœ
                taskList.forEach {
                    result.addAll(it.resultList)
                }
            }
        }
        // æ‰€æœ‰åˆ†æžç»“果入库
        if (result.isNotEmpty()) {
            dustExceptionDataRep.insert(result)
        }
        running = false
    }
    fun debugRun() {
        val result = mutableListOf<DustExceptionData>()
        val date = LocalDate.of(2023, 7, 2)
        taskList.forEach { it.init() }
        // è½®è¯¢æ•°æ®ï¼Œè®¡ç®—各个异常
        val list = dustSiteDataRep.select("YZT0JS0150043", date)
        list.takeIf { it.isNotEmpty() }?.forEach { d ->
            d?.let { taskList[0].onNextData(d) }
        }
        // å„个异常分析分别结束
        taskList[0].onDone()
        // å­˜å‚¨åˆ†æžç»“æžœ
        taskList.forEach { result.addAll(it.resultList) }
        println(result)
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataExceed.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.flightfeather.monitor.analysis.dust
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionSetting
import com.flightfeather.monitor.domain.ds1.entity.DustSiteData
import com.flightfeather.monitor.enumration.dust.ExceptionType
/**
 * æ•°æ®è¶…标异常分析
 */
class ExceptionDataExceed(config: DustExceptionSetting) : BaseExceptionContinuous(config) {
    override fun getExceptionType(): ExceptionType = ExceptionType.TYPE1
    override fun judgeException(p: DustSiteData?, n: DustSiteData): Boolean {
        return n.dustValue >= config.exceedingStandard
    }
    override fun judgeDuration(sIndex: Int, eIndex: Int): Boolean {
        return true
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataLowValue.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.flightfeather.monitor.analysis.dust
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionData
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionSetting
import com.flightfeather.monitor.domain.ds1.entity.DustSiteData
import com.flightfeather.monitor.enumration.dust.ExceptionType
/**
 * æ•°æ®è¶…低异常分析
 */
class ExceptionDataLowValue(config: DustExceptionSetting) : BaseExceptionContinuous(config) {
    override fun getExceptionType(): ExceptionType = ExceptionType.TYPE1
    override fun judgeException(p: DustSiteData?, n: DustSiteData): Boolean {
        return n.dustValue <= config.dataLow
    }
    override fun judgeDuration(sIndex: Int, eIndex: Int): Boolean {
        return true
    }
    override fun newResult(p: DustSiteData, n: DustSiteData?): DustExceptionData {
        val eType = getExceptionType()
        return DustExceptionData().apply {
            mnCode = p.mnCode
            exception = eType.des
            exceptionType = eType.value
            region = config.region
            beginTime = n?.lst
            endTime = n?.lst
        }
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionDataMissing.kt
@@ -12,6 +12,11 @@
    private var lastData: DustSiteData? = null
    override fun init() {
        super.init()
        lastData = null
    }
    override fun getExceptionType(): ExceptionType = ExceptionType.TYPE0
    override fun onNextData(data: DustSiteData) {
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionExceedingTimes.kt
@@ -16,6 +16,12 @@
    private var exceedingCount = 0
    private var startData: DustSiteData? = null
    override fun init() {
        super.init()
        exceedingCount = 0
        startData = null
    }
    override fun getExceptionType(): ExceptionType = ExceptionType.TYPE6
    override fun onNextData(data: DustSiteData) {
@@ -30,16 +36,18 @@
        if (exceedingCount >= config.dayExceedBorderlineLowNum && exceedingCount < config.dayExceedBorderlineHighNum) {
            startData?.let {
                val eType = getExceptionType()
                val t = LocalDateTime.ofInstant(it.lst.toInstant(), ZoneId.systemDefault())
                t.withHour(0)
                val sT =
                val t = LocalDateTime.ofInstant(it.lst.toInstant(), ZoneId.systemDefault()).withHour(0).withMinute(0).withSecond(0)
                val sT = Date.from(t.atZone(ZoneId.systemDefault()).toInstant())
                val n = t.plusDays(1).minusSeconds(1)
                val eT = Date.from(n.atZone(ZoneId.systemDefault()).toInstant())
                resultList.add(DustExceptionData().apply {
                    mnCode = it.mnCode
                    exception = eType.des
                    exceptionType = eType.value
                    region = config.region
//                    beginTime = if (p == null) n.lst else p.lst
//                    endTime = n.lst
                    beginTime = sT
                    endTime = eT
                })
            }
        }
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionSlideAverage.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,128 @@
package com.flightfeather.monitor.analysis.dust
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionSetting
import com.flightfeather.monitor.domain.ds1.entity.DustSiteData
import com.flightfeather.monitor.enumration.dust.ExceptionType
import kotlin.math.abs
/**
 * æ»‘动平均值突变异常
 */
class ExceptionSlideAverage(config: DustExceptionSetting) : BaseDustExceptionAnalysis(config) {
    private val historyDataList = mutableListOf<DustSiteData>()
    private val tempDataList = mutableListOf<DustSiteData>()
    private val avgListReverse = mutableListOf<Double>()
    private var startData: DustSiteData? = null
    private var lastData: DustSiteData? = null
    private var sIndex = 0
    private var eIndex = -1
    private var existException = false
    override fun init() {
        super.init()
        historyDataList.clear()
        tempDataList.clear()
        avgListReverse.clear()
        startData = null
        lastData = null
        sIndex = 0
        eIndex = -1
        existException = false
    }
    override fun getExceptionType(): ExceptionType = ExceptionType.TYPE7
    override fun onNextData(data: DustSiteData) {
        eIndex++
        if (startData == null) {
            startData = data
        }
        historyDataList.add(data)
        // æ•°æ®åŠ å…¥ä¸´æ—¶æ•°ç»„
        tempDataList.add(data)
        // æ•°æ®é‡è¶…出设置数量时,去除当前数据组首个数据
        if (tempDataList.size > config.changeTrendGroup) {
            tempDataList.removeAt(0)
        }
        // æ•°æ®é‡ç­‰äºŽè®¾ç½®æ•°é‡æ—¶ï¼Œè®¡ç®—当前数据组均值
        if (tempDataList.size == config.changeTrendGroup) {
            calAvg(tempDataList)
            if (checkSlideAvg()) {
                existException = true
            } else {
                checkResult()
            }
        }
        lastData = data
    }
    override fun onDone() {
        checkResult()
    }
    /**
     * è®¡ç®—一组数据的均值
     */
    private fun calAvg(list: List<DustSiteData>) {
        var total = .0
        val count = list.size
        if (count == 0) return
        list.forEach { total += it.dustValue }
        val avg = total / count
        avgListReverse.add(0, avg)
    }
    /**
     * è®¡ç®—数据组之间的均值差异是否连续超过限定比率
     */
    private fun checkSlideAvg(): Boolean {
        // è®¡ç®—滑动均值最低要求个数
        val minSize = config.changeTrendTimes + config.changeTrendInterval
        if (avgListReverse.size < minSize) {
            return false
        } else {
            // æ»‘动均值满足数量时,计算均值之间是否连续超过限定比率
            val rateList = mutableListOf<Double>()
            for (i in avgListReverse.indices) {
                if (i >= config.changeTrendTimes) break
                val r = calAvgChangeRate(avgListReverse[i], avgListReverse[i + config.changeTrendInterval])
                rateList.add(r)
            }
            for (y in rateList) {
                if (y < config.changeTrendRate) {
                    return false
                }
            }
            return true
        }
    }
    /**
     * è®¡ç®—滑动均值变化率
     */
    private fun calAvgChangeRate(a1: Double, a2: Double): Double {
        return if (a2 == .0) {
            1.0
        } else {
            abs(a1 - a2) / a2
        }
    }
    /**
     * å½“前数据未出现异常时,或数据循环结束时,判断后续步骤
     */
    private fun checkResult() {
        if (existException) {
            resultList.add(newResult(startData!!, lastData))
            existException = false
        }
        // åˆ¤æ–­å¹¶æ›´æ–°èµ·å§‹ç‚¹ä½ç½®
        val len = config.changeTrendGroup - 1 + config.changeTrendTimes + config.changeTrendInterval
        if ((eIndex - sIndex + 1) > len) {
            sIndex = eIndex + 1 - len
            startData = historyDataList[sIndex]
        }
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/ExceptionValueMutation.kt
@@ -18,6 +18,6 @@
    }
    override fun judgeDuration(sIndex: Int, eIndex: Int): Boolean {
        return (eIndex - sIndex) >= config.mutationNum
        return (eIndex - sIndex + 1) >= config.mutationNum
    }
}
src/main/java/com/flightfeather/monitor/analysis/dust/StatisticAnalysisController.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.flightfeather.monitor.analysis.dust
import com.flightfeather.monitor.domain.ds1.repository.DustStatisticsValueRep
import com.flightfeather.monitor.utils.DateUtil
import org.springframework.stereotype.Component
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
/**
 * æ•°æ®ç»Ÿè®¡åˆ†æžæŽ§åˆ¶å™¨
 */
@Component
class StatisticAnalysisController(private val dustStatisticsValueRep: DustStatisticsValueRep) {
    private var running1 = false
    private var running2 = false
    /**
     *
     */
    fun autoRunDailyStatics() {
        val data = dustStatisticsValueRep.findLatestData("day")
        val yesterday = LocalDate.now().minusDays(1)
        if (data == null) {
            // FIXME: 2023/10/23 åº”该是将所有数据进行统计
            dailyStatics(yesterday)
        } else {
            val date = LocalDateTime.ofInstant(data.lst.toInstant(), ZoneId.systemDefault())
            val sT = date.plusDays(1).toLocalDate()
            val du = DateUtil.findDurationDate(sT, yesterday)
            du.forEach {
                dailyStatics(it)
            }
        }
    }
    /**
     *
     */
    fun autoRunMonthlyStatics() {
        val data = dustStatisticsValueRep.findLatestData("month")
        val lastMonth = LocalDate.now().minusMonths(1).withDayOfMonth(1)
        if (data == null) {
            // FIXME: 2023/10/23 åº”该是将所有数据进行统计
            monthlyStatics(lastMonth)
        } else {
            val date = LocalDateTime.ofInstant(data.lst.toInstant(), ZoneId.systemDefault())
            val sT = date.plusMonths(1).toLocalDate()
            val du = DateUtil.findDurationMonth(sT, lastMonth)
            du.forEach {
                monthlyStatics(it)
            }
        }
    }
    fun dailyStatics(date: LocalDate) {
        running1 = true
//        if (dustStatisticsValueRep.findDataExist(date, "day")) return
        dustStatisticsValueRep.dailyStatics(date)
        running1 = false
    }
    fun monthlyStatics(date: LocalDate) {
        running2 = true
//        if (dustStatisticsValueRep.findDataExist(date, "month")) return
        dustStatisticsValueRep.monthlyStatics(date)
        running2 = false
    }
}
src/main/java/com/flightfeather/monitor/domain/ds1/entity/DustExceptionSetting.java
@@ -56,6 +56,12 @@
    @Column(name = "change_trend_rate")
    private Double changeTrendRate;
    /**
     * æ»‘动平均值变化率异常连续次数
     */
    @Column(name = "change_trend_times")
    private Integer changeTrendTimes;
    @Column(name = "exceeding_standard")
    private Double exceedingStandard;
@@ -312,6 +318,24 @@
    }
    /**
     * èŽ·å–æ»‘åŠ¨å¹³å‡å€¼å˜åŒ–çŽ‡å¼‚å¸¸è¿žç»­æ¬¡æ•°
     *
     * @return change_trend_times - æ»‘动平均值变化率异常连续次数
     */
    public Integer getChangeTrendTimes() {
        return changeTrendTimes;
    }
    /**
     * è®¾ç½®æ»‘动平均值变化率异常连续次数
     *
     * @param changeTrendTimes æ»‘动平均值变化率异常连续次数
     */
    public void setChangeTrendTimes(Integer changeTrendTimes) {
        this.changeTrendTimes = changeTrendTimes;
    }
    /**
     * @return exceeding_standard
     */
    public Double getExceedingStandard() {
src/main/java/com/flightfeather/monitor/domain/ds1/entity/DustSiteStatus.java
ÎļþÃû´Ó src/main/java/com/flightfeather/monitor/domain/ds1/entity/DustSiteLatestTime.java ÐÞ¸Ä
@@ -4,7 +4,7 @@
import javax.persistence.*;
@Table(name = "du_js_t_site_latest_time")
public class DustSiteLatestTime {
public class DustSiteStatus {
    @Id
    @Column(name = "mn_code")
    private String mnCode;
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustSiteLatestTimeMapper.kt
ÎļþÒÑɾ³ý
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustSiteStatusMapper.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.flightfeather.monitor.domain.ds1.mapper
import com.flightfeather.monitor.domain.ds1.entity.DustSiteStatus
import com.flightfeather.monitor.domain.util.MyMapper
import org.apache.ibatis.annotations.Mapper
@Mapper
interface DustSiteStatusMapper : MyMapper<DustSiteStatus?>
src/main/java/com/flightfeather/monitor/domain/ds1/mapper/DustStatisticsValueMapper.kt
@@ -3,6 +3,12 @@
import com.flightfeather.monitor.domain.ds1.entity.DustStatisticsValue
import com.flightfeather.monitor.domain.util.MyMapper
import org.apache.ibatis.annotations.Mapper
import java.time.LocalDateTime
@Mapper
interface DustStatisticsValueMapper : MyMapper<DustStatisticsValue?>
interface DustStatisticsValueMapper : MyMapper<DustStatisticsValue?> {
    fun dailyStatics(beginTime: LocalDateTime, endTime: LocalDateTime)
    fun monthlyStatics(beginTime: LocalDateTime, endTime: LocalDateTime, count: Int)
}
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionDataRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.flightfeather.monitor.domain.ds1.repository
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionData
import com.flightfeather.monitor.domain.ds1.mapper.DustExceptionDataMapper
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
import java.time.LocalDate
@Repository
class DustExceptionDataRep(private val dustExceptionDataMapper: DustExceptionDataMapper) {
    /**
     * èŽ·å–æœ€æ–°ä¸€æ¡è®°å½•
     */
    fun findLatestData(): DustExceptionData? {
        return dustExceptionDataMapper.selectOneByExample(Example(DustExceptionData::class.java).apply {
            orderBy("endTime").desc()
        })
    }
    /**
     * åˆ¤æ–­æŸå¤©çš„异常分析数据是否存在
     */
    fun findDataExist(date: LocalDate): Boolean {
        val s = date.atStartOfDay()
        val e = s.plusDays(1).minusSeconds(1)
        val res = dustExceptionDataMapper.selectOneByExample(Example(DustExceptionData::class.java).apply {
            createCriteria().andBetween("endTime", s, e)
        })
        return res != null
    }
    /**
     * å­˜å‚¨å¼‚常分析结果
     */
    fun insert(list: List<DustExceptionData>): Int {
        return dustExceptionDataMapper.insertList(list)
    }
}
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionSettingRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.flightfeather.monitor.domain.ds1.repository
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionSetting
import com.flightfeather.monitor.domain.ds1.mapper.DustExceptionSettingMapper
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
@Repository
class DustExceptionSettingRep(private val dustExceptionSettingMapper: DustExceptionSettingMapper) {
    /**
     * èŽ·å–æœ€æ–°é…ç½®
     * @param region åŒºåŽ¿
     */
    fun findLatestSetting(region: String): DustExceptionSetting? {
        return dustExceptionSettingMapper.selectOneByExample(Example(DustExceptionSetting::class.java).apply {
            createCriteria().andEqualTo("region", region)
            orderBy("version").desc()
        })
    }
}
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustSiteDataRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.flightfeather.monitor.domain.ds1.repository
import com.flightfeather.monitor.domain.ds1.entity.DustSiteData
import com.flightfeather.monitor.domain.ds1.mapper.DustSiteDataMapper
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
import java.time.LocalDate
@Repository
class DustSiteDataRep(private val dustSiteDataMapper: DustSiteDataMapper) {
    /**
     * èŽ·å–æŸä¸ªç«™ç‚¹æŸä¸€å¤©çš„æ‰€æœ‰è®°å½•
     */
    fun select(mnCode: String, date: LocalDate): List<DustSiteData?> {
        val s = date.atStartOfDay()
        val e = s.plusDays(1).minusSeconds(1)
        return dustSiteDataMapper.selectByExample(Example(DustSiteData::class.java).apply {
            createCriteria().andBetween("lst", s, e)
                .andEqualTo("mnCode", mnCode)
            orderBy("lst")
        })
    }
    /**
     * åˆ¤æ–­æŸå¤©çš„监测数据是否存在
     */
    fun findDataExist(date: LocalDate): Boolean {
        val s = date.atStartOfDay()
        val e = s.plusDays(1).minusSeconds(1)
        val res = dustSiteDataMapper.selectOneByExample(Example(DustSiteData::class.java).apply {
            createCriteria().andBetween("lst", s, e)
        })
        return res != null
    }
}
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustSiteStatusRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.flightfeather.monitor.domain.ds1.repository
import com.flightfeather.monitor.domain.ds1.entity.DustSiteStatus
import com.flightfeather.monitor.domain.ds1.mapper.DustSiteStatusMapper
import com.flightfeather.monitor.enumration.dust.DeviceStatus
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
@Repository
class DustSiteStatusRep(private val dustSiteStatusMapper: DustSiteStatusMapper) {
    /**
     * èŽ·å–ç«™ç‚¹çŠ¶æ€
     * @param status ç«™ç‚¹çŠ¶æ€
     */
    fun select(status: List<DeviceStatus>): List<DustSiteStatus?> {
        return dustSiteStatusMapper.selectByExample(Example(DustSiteStatus::class.java).apply {
            createCriteria().apply {
                status.forEach {
                    orEqualTo("deviceStatus", it.value)
                }
            }
        })
    }
}
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustStatisticsValueRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.flightfeather.monitor.domain.ds1.repository
import com.flightfeather.monitor.domain.ds1.entity.DustExceptionData
import com.flightfeather.monitor.domain.ds1.entity.DustSiteData
import com.flightfeather.monitor.domain.ds1.entity.DustStatisticsValue
import com.flightfeather.monitor.domain.ds1.mapper.DustStatisticsValueMapper
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
import java.time.Duration
import java.time.LocalDate
@Repository
class DustStatisticsValueRep(private val dustStatisticsValueMapper: DustStatisticsValueMapper) {
    fun findLatestData(type: String): DustStatisticsValue? {
        return dustStatisticsValueMapper.selectOneByExample(Example(DustStatisticsValue::class.java).apply {
            createCriteria().andEqualTo("type", type)
            orderBy("lst").desc()
        })
    }
    /**
     * åˆ¤æ–­æŸæ—¥çš„统计是否存在
     */
    fun findDataExist(date: LocalDate, type: String): Boolean {
        val s = date.atStartOfDay()
        val e = date.atStartOfDay().minusSeconds(1)
        val res = dustStatisticsValueMapper.selectOneByExample(Example(DustStatisticsValue::class.java).apply {
            createCriteria().andBetween("lst", s, e)
                .andEqualTo("type", type)
        })
        return res != null
    }
    fun dailyStatics(date: LocalDate) {
        val s = date.atStartOfDay()
        val e = s.plusDays(1).minusSeconds(1)
        dustStatisticsValueMapper.dailyStatics(s, e)
    }
    fun monthlyStatics(date: LocalDate) {
        val s = date.atStartOfDay()
        val e = s.plusMonths(1).minusSeconds(1)
        val d = Duration.between(s, e).toDays() + 1
        val dataCount = d * 96
        dustStatisticsValueMapper.monthlyStatics(s, e, dataCount.toInt())
    }
}
src/main/java/com/flightfeather/monitor/enumration/dust/DeviceStatus.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package com.flightfeather.monitor.enumration.dust
enum class DeviceStatus(val value: Int, val des: String) {
    ONLINE(0, "在线"),
    STOP(1, "停运"),
    OFFLINE(2, "离线"),
}
src/main/java/com/flightfeather/monitor/enumration/dust/ExceptionType.kt
@@ -2,8 +2,10 @@
enum class ExceptionType(val value:Int, val des:String) {
    TYPE0(0, "断网或掉线"),
    TYPE1(1, "数据超低异常"),
    TYPE3(3, "数据长时段无波动"),
    TYPE4(4, "量级突变异常"),
    TYPE5(5, "临近超标异常"),
    TYPE6(6, "单日超标次数临近处罚异常"),
    TYPE7(7, "滑动平均值突变异常"),
}
src/main/java/com/flightfeather/monitor/scheduledtasks/BaseTimingTask.kt
@@ -1,14 +1,18 @@
package cn.flightfeather.supervision.timingtask
package com.flightfeather.monitor.scheduledtasks
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.time.LocalDateTime
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
/**
 * å®šæ—¶ä»»åŠ¡åŸºç±»
 */
abstract class BaseTimingTask {
    companion object {
        val log: Logger = LoggerFactory.getLogger(BaseTimingTask::class.java)
    }
    // è®°å½•上次任务执行的时间点,单位:毫秒
    private var lastTime: LocalDateTime = LocalDateTime.MIN
src/main/java/com/flightfeather/monitor/scheduledtasks/DustDailyStatisticAnalysisTask.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.flightfeather.monitor.scheduledtasks
import com.flightfeather.monitor.analysis.dust.StatisticAnalysisController
import lombok.extern.slf4j.Slf4j
import org.springframework.stereotype.Component
import java.time.LocalDateTime
@Component
class DustDailyStatisticAnalysisTask(private val statisticAnalysisController: StatisticAnalysisController) :
    BaseTimingTask() {
    override val period: Long = 15
    override fun execute(localtime: LocalDateTime) {
//        println("日分析轮询")
//        println(localtime)
        if (localtime.hour == 9 && localtime.minute == 0) {
            doTask(localtime)
        }
    }
    override fun doTask(localtime: LocalDateTime) {
        log.info("日分析执行")
        statisticAnalysisController.autoRunDailyStatics()
    }
}
src/main/java/com/flightfeather/monitor/scheduledtasks/DustExceptionAnalysisTask.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.flightfeather.monitor.scheduledtasks
import com.flightfeather.monitor.analysis.dust.ExceptionAnalysisController
import org.springframework.stereotype.Component
import java.time.LocalDateTime
@Component
class DustExceptionAnalysisTask(private val exceptionAnalysisController: ExceptionAnalysisController) :
    BaseTimingTask() {
    override val period: Long = 15
    override fun execute(localtime: LocalDateTime) {
//        println("异常分析轮询")
//        println(localtime)
        if (localtime.hour == 8 && localtime.minute == 0) {
            doTask(localtime)
        }
    }
    override fun doTask(localtime: LocalDateTime) {
        log.info("异常分析执行")
        exceptionAnalysisController.init()
        exceptionAnalysisController.autoRun()
    }
}
src/main/java/com/flightfeather/monitor/scheduledtasks/DustMonthlyStatisticAnalysisTask.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.flightfeather.monitor.scheduledtasks
import com.flightfeather.monitor.analysis.dust.StatisticAnalysisController
import org.springframework.stereotype.Component
import java.time.LocalDateTime
@Component
class DustMonthlyStatisticAnalysisTask(private val statisticAnalysisController: StatisticAnalysisController) :
    BaseTimingTask() {
    override val period: Long = 15
    override fun execute(localtime: LocalDateTime) {
//        println("月分析轮询")
//        println(localtime)
        if (localtime.dayOfMonth == 2 && localtime.hour == 0 && localtime.minute == 0) {
            doTask(localtime)
        }
    }
    override fun doTask(localtime: LocalDateTime) {
        log.info("月分析执行")
        statisticAnalysisController.autoRunMonthlyStatics()
    }
}
src/main/java/com/flightfeather/monitor/scheduledtasks/ScheduledTaskController.java
ÎļþÒÑɾ³ý
src/main/java/com/flightfeather/monitor/scheduledtasks/TaskController.kt
@@ -1,6 +1,7 @@
package com.flightfeather.monitor.scheduledtasks
import cn.flightfeather.supervision.timingtask.BaseTimingTask
import lombok.extern.slf4j.Slf4j
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import java.time.LocalDateTime
@@ -13,23 +14,18 @@
/**
 * æ•°æ®èŽ·å–æŽ§åˆ¶å™¨
 */
@Slf4j
@Component
class TaskController(
        /*实例名 ç±»å*/
//    fetchVOC: TaskFetchVOC,
//    pushFume: TaskPushFume,
//    ledgerCopy: TaskLedgerCopy,
//    ledgerRemind: TaskLedgerRemind,
//    taskJinAnLampEnterBaseInfo: TaskJinAnLampEnterBaseInfo,
//    taskJinAnLampDeviceData: TaskJinAnLampDeviceData,
//    taskJinAnConstructionSiteInfo: TaskJinAnConstructionSiteInfo,
//    taskJinAnHourlyDustData: TaskJinAnHourlyDustData
    dustExceptionAnalysisTask: DustExceptionAnalysisTask,
    dustDailyStatisticAnalysisTask: DustDailyStatisticAnalysisTask,
    dustMonthlyStatisticAnalysisTask: DustMonthlyStatisticAnalysisTask,
) {
    companion object {
        private const val FETCH_PERIOD_MIN = 1L * 60
        private const val MAINTAIN_PERIOD_MIN = 5L * 60
        val LOGGER = LoggerFactory.getLogger(TaskController::class.java)
        val log: Logger = LoggerFactory.getLogger(TaskController::class.java)
    }
    private val timeTask = mutableListOf<BaseTimingTask>()
@@ -39,13 +35,13 @@
    private var maintainTime: Date = Date()
    init {
        LOGGER.info("添加定时任务")
        log.info("添加定时任务")
        timeTask.clear()
       /*做的定时任务加进来*/
        LOGGER.info("添加定时任务完成,任务总计${timeTask.size}个")
        timeTask.add(dustExceptionAnalysisTask)
        timeTask.add(dustDailyStatisticAnalysisTask)
        timeTask.add(dustMonthlyStatisticAnalysisTask)
        log.info("添加定时任务完成,任务总计${timeTask.size}个")
    }
    fun run() {
@@ -54,7 +50,6 @@
    }
    private fun fetchTask(isFirst: Boolean = false) {
        val cal = Calendar.getInstance()
        val time = LocalTime.now()
        val sec = time.second
        val delay = 60L - sec
src/main/java/com/flightfeather/monitor/utils/DateUtil.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.flightfeather.monitor.utils
import java.time.LocalDate
object DateUtil {
    fun findDurationDate(s: LocalDate, e: LocalDate): List<LocalDate> {
        val res = mutableListOf<LocalDate>()
        while (s.isBefore(e) || s.isEqual(e)) {
            res.add(s)
            s.plusDays(1)
        }
        return res
    }
    fun findDurationMonth(s: LocalDate, e: LocalDate): List<LocalDate> {
        val res = mutableListOf<LocalDate>()
        while (s.monthValue <= e.monthValue) {
            res.add(s)
            s.plusMonths(1)
        }
        return res
    }
}
src/main/resources/application.yml
@@ -2,17 +2,17 @@
  datasource:
    ds1:
      driver-class-name: com.mysql.cj.jdbc.Driver
#      url: jdbc:mysql://localhost:3306/fume
#      username: fume
#      password: fume_feiyu2023
      url: jdbc:mysql://localhost:3306/fume
      username: fume
      password: fume_feiyu2023
#      url: jdbc:mysql://localhost:3306/qianduan_sql
#      username: root
#      password: 1234
      url: jdbc:mysql://localhost:3306/fume
      username: root
      password: 123456
#      url: jdbc:mysql://localhost:3306/fume
#      username: root
#      password: 123456
mybatis:
  configuration:
src/main/resources/generator/generatorConfig4ds1.xml
@@ -50,10 +50,10 @@
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
<!--               enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="du_js_t_site_latest_time" domainObjectName="DustSiteLatestTime"-->
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
<!--               enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="du_js_t_site_latest_time" domainObjectName="DustSiteStatus"
               enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" selectByExampleQueryId="false"/>
<!--        <table tableName="du_js_t_site_map" domainObjectName="DustSiteMap"-->
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
@@ -62,10 +62,10 @@
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
<!--               enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="dust_exception_setting" domainObjectName="DustExceptionSetting"
               enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" selectByExampleQueryId="false"/>
<!--        <table tableName="dust_exception_setting" domainObjectName="DustExceptionSetting"-->
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
<!--               enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="dust_global_setting" domainObjectName="DustGlobalSetting"-->
<!--               enableCountByExample="false"-->
<!--               enableUpdateByExample="false" enableDeleteByExample="false"-->
src/main/resources/mapper/ds1/DustExceptionSettingMapper.xml
@@ -23,6 +23,7 @@
    <result column="change_trend_group" jdbcType="INTEGER" property="changeTrendGroup" />
    <result column="change_trend_interval" jdbcType="INTEGER" property="changeTrendInterval" />
    <result column="change_trend_rate" jdbcType="DOUBLE" property="changeTrendRate" />
    <result column="change_trend_times" jdbcType="INTEGER" property="changeTrendTimes" />
    <result column="exceeding_standard" jdbcType="DOUBLE" property="exceedingStandard" />
  </resultMap>
  <sql id="Base_Column_List">
@@ -32,6 +33,6 @@
    id, user, update_time, region, version, miss_data_minutes, data_low, long_time_no_change, 
    mutation_num, mutation_rate, near_exceed_low_value, near_exceed_high_value, near_exceed_num, 
    day_exceed_borderline_low_num, day_exceed_borderline_high_num, change_trend_group, 
    change_trend_interval, change_trend_rate, exceeding_standard
    change_trend_interval, change_trend_rate, change_trend_times, exceeding_standard
  </sql>
</mapper>
src/main/resources/mapper/ds1/DustSiteStatusMapper.xml
ÎļþÃû´Ó src/main/resources/mapper/ds1/DustSiteLatestTimeMapper.xml ÐÞ¸Ä
@@ -1,7 +1,7 @@
<?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.monitor.domain.ds1.mapper.DustSiteLatestTimeMapper">
  <resultMap id="BaseResultMap" type="com.flightfeather.monitor.domain.ds1.entity.DustSiteLatestTime">
<mapper namespace="com.flightfeather.monitor.domain.ds1.mapper.DustSiteStatusMapper">
  <resultMap id="BaseResultMap" type="com.flightfeather.monitor.domain.ds1.entity.DustSiteStatus">
    <!--
      WARNING - @mbg.generated
    -->
src/main/resources/mapper/ds1/DustStatisticsValueMapper.xml
@@ -22,4 +22,42 @@
    -->
    id, mn_code, lst, day_avg, min, max, day_online, day_valid, day_exceeding, type
  </sql>
  <insert id="dailyStatics">
    insert into  dust_statistics_value(mn_code,lst,day_avg,min,max,day_online,day_valid,day_exceeding,type)
    select  a.*
    from  (select
    mn_code as mn_code,
    DATE(lst) as lst,
    ROUND(AVG(dust_value),3)  as day_avg,
    min(dust_value) as min,
    max(dust_value) as max,
    CONCAT(ROUND(COUNT(*)/96*100, 2), '%')  as day_online,
    CONCAT(ROUND(SUM(CASE WHEN dust_value >0 THEN 1 ELSE 0 END)/96 *100, 2), '%') as day_valid,
    CONCAT(ROUND(SUM(CASE WHEN dust_value >= 1  THEN 1 ELSE 0 END)/96*100,2),'%') as  day_exceeding,
    'day' as type
    from ja_t_dust_site_data_info
    where  lst between #{beginTime} and #{endTime}
    GROUP BY mn_code,DATE(lst)
    ) as a
  </insert>
  <insert id="monthlyStatics">
    insert into  dust_statistics_value(mn_code,lst,day_avg,min,max,day_online,day_valid,day_exceeding,type)
    select  a.*
    from  (
    SELECT
    mn_code AS mn_code,
    DATE_FORMAT(lst, '%Y-%m-01') AS month,
    ROUND(AVG(dust_value), 3) AS month_avg,
    MIN(dust_value) AS min,
    MAX(dust_value) AS max,
    CONCAT(ROUND(COUNT(*) / #{count} * 100, 2), '%') AS month_online,
    CONCAT(ROUND(SUM(CASE WHEN flag = 'N' OR flag = 'A' THEN 1 ELSE 0 END) / #{count} * 100, 2), '%') AS month_valid,
    CONCAT(ROUND(SUM(CASE WHEN dust_value >= 1 THEN 1 ELSE 0 END) / #{count} * 100, 2), '%') AS month_exceeding,
    'month' as type
    FROM ja_t_dust_site_data_info
    WHERE lst BETWEEN #{beginTime} and #{endTime}
    GROUP BY mn_code, DATE_FORMAT(lst, '%Y-%m-01')
    ) as a
  </insert>
</mapper>
src/test/java/com/flightfeather/monitor/MonitorApplicationTests.java
ÎļþÃû´Ó src/test/java/com/flightfeather/monitor/QianduanApplicationTests.java ÐÞ¸Ä
@@ -9,7 +9,7 @@
import java.util.Locale;
@SpringBootTest
class QianduanApplicationTests {
class MonitorApplicationTests {
    @Test
    void contextLoads() throws ParseException {
src/test/java/com/flightfeather/monitor/analysis/dust/ExceptionAnalysisControllerTest.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.flightfeather.monitor.analysis.dust
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.context.junit4.SpringRunner
import java.time.LocalDate
@RunWith(SpringRunner::class)
@ExtendWith(SpringExtension::class)
@SpringBootTest
class ExceptionAnalysisControllerTest {
    @Autowired
    lateinit var exceptionAnalysisController: ExceptionAnalysisController
    @Test
    fun autoRun() {
        exceptionAnalysisController.init()
        exceptionAnalysisController.autoRun()
    }
    @Test
    fun run() {
        exceptionAnalysisController.init()
        val d = LocalDate.of(2023, 7, 2)
        exceptionAnalysisController.run(d)
//        exceptionAnalysisController.debugRun()
    }
}
src/test/java/com/flightfeather/monitor/analysis/dust/StatisticAnalysisControllerTest.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.flightfeather.monitor.analysis.dust
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.context.junit4.SpringRunner
import java.time.LocalDate
@RunWith(SpringRunner::class)
@ExtendWith(SpringExtension::class)
@SpringBootTest
class StatisticAnalysisControllerTest {
    @Autowired
    lateinit var statisticAnalysisController: StatisticAnalysisController
    @Test
    fun dailyStatics() {
        val d = LocalDate.of(2023, 7, 2)
        statisticAnalysisController.dailyStatics(d)
    }
    @Test
    fun monthlyStatics() {
        val d = LocalDate.of(2023, 7, 1)
        statisticAnalysisController.monthlyStatics(d)
    }
    @Test
    fun autoRunDailyStatics() {
        statisticAnalysisController.autoRunDailyStatics()
    }
    @Test
    fun autoRunMonthlyStatics() {
        statisticAnalysisController.autoRunMonthlyStatics()
    }
}