已修改34个文件
已添加16个文件
1211 ■■■■ 文件已修改
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/AopOutput.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/score/AopCreditCode.kt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/CrossTimeChangeManager.kt 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/ProblemInfo.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/ScenePbGroup.kt 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/package.info 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/report/DataSource.kt 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/executor/BackgroundTaskCtrl.kt 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTask.kt 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTaskStatus.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTaskStatusJsonSerializer.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/utils/Constant.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/utils/JsonUtil.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/DustDataResultMapper.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/ProblemlistMapper.kt 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/EvaluationRep.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/MonitorDataRep.kt 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/ProblemRep.kt 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/TaskRep.kt 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds2/repository/OverallEvaluationRep.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DomaincatalogService.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/MonitorDataService.kt 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemlistService.kt 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemtypeService.kt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/TaskService.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomaincatalogServiceImpl.kt 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/MonitorDataServiceImpl.kt 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemlistServiceImpl.kt 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemtypeServiceImpl.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SubtaskServiceImpl.kt 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/TaskServiceImpl.kt 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AreaVo.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/MonitorDataController.kt 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ProblemlistController.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/TaskController.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/LocalDateTimeAdapter.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketMessage.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketMessageParser.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketSendMessageUtil.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketSenderHandler.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/config/SPTextWebSocketHandler.kt 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/socket/processor/WebSocketReceiver.kt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/DustDataResultMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/ProblemlistMapper.xml 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/ScenseMapper.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/SubtaskMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/cn/flightfeather/supervision/business/autooutput/AopEvaluationTest.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/cn/flightfeather/supervision/business/crosstimechange/CrossTimeChangeManagerTest.kt 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomaincatalogServiceImplTest.kt 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/AopOutput.kt
@@ -8,6 +8,7 @@
import cn.flightfeather.supervision.domain.ds1.mapper.EvaluationMapper
import cn.flightfeather.supervision.domain.ds1.mapper.ItemevaluationMapper
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import tk.mybatis.mapper.entity.Example
/**
@@ -23,6 +24,7 @@
    /**
     * å°†è¯„分记录输出至数据库
     */
    @Transactional
    fun toDbEvaluation(evaluationScene: AopDataSource.EvaluationScene, p: Pair<Evaluation, List<Itemevaluation>>) {
        //去除已有记录
        evaluationMapper.deleteByExample(Example(Evaluation::class.java).apply {
@@ -40,6 +42,7 @@
    /**
     * å°†è¯„分记录更新至数据库
     */
    @Transactional
    fun updateDbEvaluation(evaluationScene: AopDataSource.EvaluationScene, p: Pair<Evaluation, List<Itemevaluation>>) {
        evaluationMapper.updateByPrimaryKey(p.first)
        p.second.forEach { il -> itemevaluationMapper.updateByPrimaryKey(il) }
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/score/AopCreditCode.kt
@@ -10,6 +10,8 @@
import cn.flightfeather.supervision.domain.ds2.repository.UserMapRep
import org.springframework.stereotype.Component
import java.time.LocalDate
import java.time.ZoneId
import java.util.*
/**
 * æ ¹æ®è‡ªåŠ¨è¯„ä¼°[AopEvaluation]结果生成环信码
@@ -33,9 +35,19 @@
            userMapRep.findFromSupervision(it)?.let { s ->
                // ä»Žé£žç¾½ç›‘管系统中查找评分
                val e = evaluationRep.findByScene(s.guid, date)
                e?.resultscorebef?.toInt()?.let {score ->
                if (e.isNotEmpty()) {
                    // æ ¹æ®è¯„分生成对应的环信码
                    var score = 0
                    e.forEach {eva ->
                        val s = eva?.resultscorebef?.toInt() ?: 0
                        if (s > score) score = s
                    }
                    overallEvaluationRep.insertOrUpdateOne(it?.guid, score, sceneType, date, endDate)
                } else {
                    // TODO: 2024/12/6 å½“没有找到自动评分记录时,采用历史最新的环信码记录作为本期记录
                    overallEvaluationRep.selectLatest(it?.guid)?.let {o ->
                        overallEvaluationRep.insertOrUpdateOne(o.biGuid, o.oeScore, sceneType, date, endDate)
                    }
                }
            }
        }
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/CrossTimeChangeManager.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,190 @@
package cn.flightfeather.supervision.business.crosstimechange
import cn.flightfeather.supervision.common.utils.DateUtil
import cn.flightfeather.supervision.common.utils.ExcelUtil
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.ds1.repository.ProblemRep
import cn.flightfeather.supervision.domain.ds1.repository.SubTaskRep
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.springframework.stereotype.Component
import java.io.File
import java.io.FileOutputStream
import java.time.format.DateTimeFormatter
/**
 * è·¨æ—¶é—´è·¨æœˆåº¦æ•´æ”¹
 * @date 2024/12/20
 * @author feiyu02
 */
@Component
class CrossTimeChangeManager(private val subTaskRep: SubTaskRep, private val problemRep: ProblemRep) {
    /**
     * æ‰§è¡Œè·¨æœˆåº¦è·¨æ—¶é—´æ•´æ”¹åˆ†æž
     * @param areaVo ç­›é€‰æ¡ä»¶ï¼ŒåŒ…括区域、场景类型、时间范围
     */
    fun execute(areaVo: AreaVo, fileName: String) {
        val pbGroupList = searchProblem(areaVo)
        pbGroupList.forEach { changeAnalysis(it) }
        formatToExcel(areaVo, pbGroupList, fileName)
    }
    /**
     * æŸ¥è¯¢èŒƒå›´å†…的场景及各月度问题
     */
    fun searchProblem(areaVo: AreaVo): List<ScenePbGroup> {
        // èŽ·å–èŒƒå›´å†…æ‰€æœ‰çš„å·¡æŸ¥è®°å½•åŠå…·ä½“é—®é¢˜
        val summary = subTaskRep.findSummary(areaVo)
        // æŒ‰ç…§åœºæ™¯è¿›è¡Œå½’ç±»
        val sceneMap = mutableMapOf<String?, ScenePbGroup>()
        summary.forEach {
            if (!sceneMap.containsKey(it.sceneId)) {
                sceneMap[it.sceneId] = ScenePbGroup().apply {
                    scene = it.scene
                }
            }
            sceneMap[it.sceneId]?.apply {
                pbGroup.add(ProblemInfo().apply {
                    subtask = it.subtask
                    val pList = problemRep.find(Problemlist().apply {
                        stguid = it.stGuid
                    })
                    pbList.addAll(pList)
                })
            }
        }
        // å°†å½’类好的各场景问题按照巡查时间升序排列并转换为数组结构
        val res = mutableListOf<ScenePbGroup>()
        sceneMap.forEach { (t, u) ->
            u.pbGroup.sortBy { it?.subtask?.planstarttime }
            res.add(u)
        }
        // å°†åœºæ™¯æŒ‰ç…§å”¯ä¸€ç¼–号升序排列(非必要)
        res.sortBy { it.scene?.index }
        return res
    }
    /**
     * åˆ†æžå•个场景各月问题是否可以整改
     */
    fun changeAnalysis(scenePbGroup: ScenePbGroup) {
        scenePbGroup.pbGroup.forEachIndexed {i,it ->
            it?.pbList?.forEach { p ->
                // å·²æ•´æ”¹çš„问题略过
                if (p?.ischanged == true) return@forEach
                // æ‰¾åˆ°ç»“果(指有一个月未出现此问题,或者出现了此问题但已整改),则允许将此历史问题作为已整改
                var found = false
                // å‘后续月度查找是否有相同的问题出现
                var index = i + 1
                while (!found && index < scenePbGroup.pbGroup.size) {
                    val nextGroup = scenePbGroup.pbGroup[index]
                    val result = nextGroup?.pbList?.find { nP ->
                        nP?.ptguid == p?.ptguid
                    }
                    // è¯¥æœˆæœªå‡ºçŽ°æ­¤é—®é¢˜ï¼Œæˆ–è€…å‡ºçŽ°äº†æ­¤é—®é¢˜ä½†å·²æ•´æ”¹
                    if (result == null || result.ischanged == true) {
                        found = true
                    }
                    index++
                }
                // è‹¥è¯¥é—®é¢˜ç¬¦åˆæ•´æ”¹æ¡ä»¶ï¼Œåˆ™æ·»åŠ è‡³å¯æ•´æ”¹åˆ—è¡¨
                if (found) {
                    it.pbChangeList.add(p)
                }
            }
        }
    }
    /**
     * æ ¼å¼åŒ–输出至excel文件
     */
    fun formatToExcel(areaVo: AreaVo, pbGroupList: List<ScenePbGroup>, fileName: String) {
        if (pbGroupList.isEmpty()) return
        val h = mutableListOf<MutableList<Any>>()
        val c = mutableListOf<MutableList<Any>>()
        // ç”Ÿæˆè¡¨å¤´
        val h1 = mutableListOf<Any>("唯一编号", "场景")
        val monHead = mutableListOf<String>()
        var time = areaVo.starttime?.toLocalDate()
        val end = areaVo.endtime?.toLocalDate()
        // æ­¤å¤„开始时间应为月初,结束时间应为月末,则可以直接用isBefore比较
        while (time?.isBefore(end) == true) {
            monHead.add(time.format(DateTimeFormatter.ofPattern("YYYY-MM")))
            time = time.plusMonths(1)
        }
        monHead.forEach {
            val str = it.split("-")[1] + "月"
            h1.addAll(listOf(str + "问题", str + "未整改", str + "未整改数"))
        }
        monHead.forEach {
            val str = it.split("-")[1] + "月"
            h1.addAll(listOf(str + "可整改", str + "原整改数", str + "新增可整改数"))
        }
        h.add(h1)
        // ç”Ÿæˆå†…容
        pbGroupList.forEach {pbg ->
            val index = pbg.scene?.index ?: ""
            val name = pbg.scene?.name ?: ""
            val problemContent = mutableListOf<Any>()
            monHead.forEach {mH ->
                val stp = pbg.pbGroup.find { pbi ->
                    DateUtil.DateToString(pbi?.subtask?.planstarttime, DateUtil.DateStyle.YYYY_MM) == mH
                }
                if (stp == null) {
                    problemContent.addAll(listOf("/", "/", "/"))
                } else {
                    // é—®é¢˜
                    problemContent.add(stp.pbList.mapIndexed { i, pb -> "${i+1}、${pb?.problemname}" }.joinToString
                        ("\n"))
                    val unchanged = stp.pbList.filter { pb-> pb?.ischanged != true }
                    // æœªæ•´æ”¹
                    problemContent.add(unchanged.mapIndexed { i, pb -> "${i+1}、${pb?.problemname}" }.joinToString("\n"))
                    // æœªæ•´æ”¹æ•°
                    problemContent.add(unchanged.size)
                }
            }
            val willChangeContent = mutableListOf<Any>()
            monHead.forEach {mH ->
                val stp = pbg.pbGroup.find { pbi ->
                    DateUtil.DateToString(pbi?.subtask?.planstarttime, DateUtil.DateStyle.YYYY_MM) == mH
                }
                if (stp == null) {
                    willChangeContent.addAll(listOf("/", "/", "/"))
                } else {
                    // å¯æ•´æ”¹
                    willChangeContent.add(stp.pbChangeList.mapIndexed { i, pb -> "${i+1}、${pb?.problemname}" }
                        .joinToString("\n"))
                    val changed = stp.pbList.filter { pb-> pb?.ischanged == true }
                    // åŽŸæ•´æ”¹æ•°
                    willChangeContent.add(changed.size)
                    // æ–°å¢žå¯æ•´æ”¹æ•°
                    willChangeContent.add(stp.pbChangeList.size)
                }
            }
            val row = mutableListOf<Any>()
            row.add(index)
            row.add(name)
            row.addAll(problemContent)
            row.addAll(willChangeContent)
            c.add(row)
        }
        // ç”Ÿæˆæ–‡ä»¶
        val file = File("target/${fileName}")
        val out = FileOutputStream(file)
        ExcelUtil.write2(out, h.map { it.toTypedArray() }, c.map { it.toTypedArray() }.toMutableList())
    }
}
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/ProblemInfo.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package cn.flightfeather.supervision.business.crosstimechange
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.ds1.entity.Subtask
/**
 * é—®é¢˜æ•´æ”¹æƒ…况
 * @date 2024/12/20
 * @author feiyu02
 */
class ProblemInfo {
    // å·¡æŸ¥ä»»åŠ¡
    var subtask: Subtask? = null
    // åŽ†å²é—®é¢˜
    val pbList = mutableListOf<Problemlist?>()
    // å¯è¢«è·¨æ—¶é—´è·¨æœˆåº¦æ•´æ”¹çš„问题
    val pbChangeList = mutableListOf<Problemlist?>()
}
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/ScenePbGroup.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package cn.flightfeather.supervision.business.crosstimechange
import cn.flightfeather.supervision.domain.ds1.entity.Scense
/**
 * åœºæ™¯è·¨æœˆåº¦é—®é¢˜ç»„
 * @date 2024/12/20
 * @author feiyu02
 */
class ScenePbGroup {
    // åœºæ™¯
    var scene: Scense? = null
    // åŽ†æ¥å„æœˆä»½çš„é—®é¢˜æƒ…å†µ
    val pbGroup = mutableListOf<ProblemInfo?>()
}
src/main/kotlin/cn/flightfeather/supervision/business/crosstimechange/package.info
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
跨时间跨月度整改
对于同一家场景,以N个月为周期,需要判断每个月未整改的问题在后续月份监管中是否未出现,若未出现,则认为该问题已整改
具体逻辑
1. ç­›é€‰è¿™N个月的问题;
2. å¾ªçŽ¯åˆ¤æ–­æ¯ä¸ªæœˆçš„æ¯ä¸ªæœªæ•´æ”¹é—®é¢˜ï¼Œåœ¨åŽç»­æœˆä»½ä¸­ï¼Œè‹¥è‡³å°‘æœ‰ä¸€ä¸ªæœˆæœªå‡ºçŽ°è¿‡è¯¥é—®é¢˜ï¼Œåˆ™è®¤ä¸ºè¯¥é—®é¢˜å·²æ•´æ”¹
src/main/kotlin/cn/flightfeather/supervision/business/report/DataSource.kt
@@ -68,7 +68,7 @@
     */
    fun areaName(): String {
        val t = dbMapper.taskMapper.selectByPrimaryKey(config.topTaskGuid)
        return "${DateUtil.DateToString(t.starttime, DateUtil.DateStyle.YYYY_MM_CN)}${t.districtname}${if (area != t.districtname) area else ""}${Constant.SceneType.getDes(config.sceneType)}"
        return "${DateUtil.DateToString(config.startTime, DateUtil.DateStyle.YYYY_MM_CN)}${t.districtname}${if (area != t.districtname) area else ""}${Constant.SceneType.getDes(config.sceneType)}"
    }
    /**
@@ -92,12 +92,12 @@
            if (area.isBlank()) area = it.districtname ?: ""
        }
        //1. æŸ¥æ‰¾ç‰¹å®šçš„巡查任务或者所有的计划巡查任务
        val taskSceneIdList = dbMapper.scenseMapper.getSceneByType(config.topTaskGuid, config.sceneType,
            config.townCode).map { it.guid ?: "" }
        // ç»Ÿè®¡æ€»ä»»åŠ¡ä¸‹æ‰€æœ‰åœºæ™¯
        if (config.allScene) {
            //1. æŸ¥æ‰¾ç‰¹å®šçš„巡查任务或者所有的计划巡查任务
            val taskSceneIdList = dbMapper.scenseMapper.getSceneByType(config.topTaskGuid, config.sceneType,
                config.townCode).map { it.guid ?: "" }
            val subTaskList = dbMapper.subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().apply {
                    if (taskSceneIdList.isNotEmpty()) andIn("scenseid", taskSceneIdList)
src/main/kotlin/cn/flightfeather/supervision/common/executor/BackgroundTaskCtrl.kt
@@ -1,6 +1,7 @@
package cn.flightfeather.supervision.common.executor
import cn.flightfeather.supervision.common.exception.BizException
import cn.flightfeather.supervision.socket.WebSocketSendMessageUtil
import org.springframework.stereotype.Component
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors
@@ -37,7 +38,10 @@
                throw BizException("无法重复创建任务")
            }
        }
        val t = BgTask(type, id, name, task)
        val t = BgTask(type, id, name, task) { status ->
            // å‘送消息
            WebSocketSendMessageUtil.sendBgTaskMessage(status)
        }
        taskSet[id] = t
        return t
    }
@@ -62,7 +66,9 @@
            }
        } else {
            task.ready()
            task.future = executorService.submit { task.execute() }
            task.future = executorService.submit {
                task.execute()
            }
            return task
        }
    }
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTask.kt
@@ -11,13 +11,14 @@
    val id: String,
    val name: String,
    private val task: () -> Boolean,
    private val onStatusChange: (status: BgTaskStatus) -> Unit
) {
    var taskStatus = BgTaskStatus(type, id, name)
    var future: Future<*>? = null
    fun ready() {
        taskStatus.status = TaskStatus.RUNNING
        taskStatus.startTime = LocalDateTime.now()
        setStatus(TaskStatus.RUNNING)
    }
    fun execute() {
@@ -31,24 +32,29 @@
    }
    fun success() {
        taskStatus.status = TaskStatus.SUCCESS
        complete()
        setStatus(TaskStatus.SUCCESS)
    }
    fun fail() {
        taskStatus.status = TaskStatus.FAIL
        complete()
        setStatus(TaskStatus.FAIL)
    }
    fun shutdown() {
        if (future?.isCancelled == false && !future!!.isDone) {
            future!!.cancel(true)
        }
        taskStatus.status = TaskStatus.SHUTDOWN
        complete()
        setStatus(TaskStatus.SHUTDOWN)
    }
    fun complete() {
        taskStatus.endTime = LocalDateTime.now()
    }
    fun setStatus(status: TaskStatus) {
        taskStatus.status = status
        onStatusChange(taskStatus)
    }
}
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTaskStatus.kt
@@ -1,5 +1,7 @@
package cn.flightfeather.supervision.common.executor
import cn.flightfeather.supervision.socket.LocalDateTimeAdapter
import com.google.gson.annotations.JsonAdapter
import java.time.Duration
import java.time.LocalDateTime
@@ -15,12 +17,15 @@
    var status: TaskStatus = TaskStatus.WAITING
    //    å¼€å§‹æ—¶é—´
    @JsonAdapter(LocalDateTimeAdapter::class)
    var startTime: LocalDateTime? = null
    //    ç»“束时间
    @JsonAdapter(LocalDateTimeAdapter::class)
    var endTime: LocalDateTime? = null
    //    åˆ›å»ºæ—¶é—´
    @JsonAdapter(LocalDateTimeAdapter::class)
    var createTime: LocalDateTime = LocalDateTime.now()
    //    è¿è¡Œæ—¶é•¿ï¼ˆç§’)
src/main/kotlin/cn/flightfeather/supervision/common/executor/BgTaskStatusJsonSerializer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package cn.flightfeather.supervision.common.executor;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * BgTaskStatus类的自定义序列化类 è§£å†³äº†è®¡ç®—属性无法序列化的问题
 * by hc 2024.12.10
 */
public class BgTaskStatusJsonSerializer implements JsonSerializer<BgTaskStatus> {
    @Override
    public JsonElement serialize(BgTaskStatus bgTaskStatus, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject jsonObject = new JsonObject();
        // åºåˆ—化type
        jsonObject.addProperty("type", String.valueOf(bgTaskStatus.getType()));
        // åºåˆ—化id
        jsonObject.addProperty("id", bgTaskStatus.getId());
        // åºåˆ—化name
        jsonObject.addProperty("name", bgTaskStatus.getName());
        // åºåˆ—化status
        jsonObject.addProperty("status", String.valueOf(bgTaskStatus.getStatus()));
        // åºåˆ—化startTime
        jsonObject.addProperty("startTime", formatLocalDateTime(bgTaskStatus.getStartTime()));
        // åºåˆ—化endTime
        jsonObject.addProperty("endTime", formatLocalDateTime(bgTaskStatus.getEndTime()));
        // åºåˆ—化createTime
        jsonObject.addProperty("createTime", formatLocalDateTime(bgTaskStatus.getCreateTime()));
        // åºåˆ—化 è®¡ç®—属性runTime
        jsonObject.addProperty("runTime", bgTaskStatus.getRunTime());
        // åºåˆ—化extra
        if (bgTaskStatus.getExtra() != null) {
            jsonObject.add("extra", context.serialize(bgTaskStatus.getExtra()));
        }
        return jsonObject;
    }
    private String formatLocalDateTime(LocalDateTime localDateTime) {
        // å¦‚æžœLocalDateTime为null,则返回null
        if (localDateTime == null) {
            return null;
        }
        // æ ¼å¼åŒ–LocalDateTime
        return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime);
    }
}
src/main/kotlin/cn/flightfeather/supervision/common/utils/Constant.kt
@@ -39,6 +39,7 @@
        TYPE9("9","道路扬尘监测点"), TYPE10("10","道路"),
        TYPE11("11","河流断面"), TYPE12("12","工业园区"),
        TYPE13("13","无固定场景"),TYPE14("14","堆场"),
        TYPE15("15","精品小区"),
        TYPE99("99","其他");
        companion object {
@@ -211,6 +212,17 @@
        MULTI_MODE("multi_mode", "多选模式"),
    }
    // socket消息类型
    enum class SocketMessageType(val value: Int, val des: String){
        BG_TASK(1, "后台任务"),
        BUSINESS_LOG(2, "业务日志"),
    }
    // socket心跳消息类型
    enum class SocketHeartMessageType(val value: Int, val des: String){
        HEART_MESSAGE_TYPE(0, "心跳机制")
    }
    companion object {
        //问题审核
src/main/kotlin/cn/flightfeather/supervision/common/utils/JsonUtil.kt
@@ -1,9 +1,13 @@
package cn.flightfeather.supervision.common.utils
import cn.flightfeather.supervision.common.executor.BgTaskStatus
import cn.flightfeather.supervision.common.executor.BgTaskStatusJsonSerializer
import com.google.gson.Gson
import com.google.gson.GsonBuilder
object JsonUtil {
    val gson: Gson = GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create()
    val gson: Gson = GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
        .registerTypeAdapter(BgTaskStatus::class.java, BgTaskStatusJsonSerializer())
        .create()
}
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/DustDataResultMapper.kt
@@ -2,7 +2,11 @@
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
import cn.flightfeather.supervision.domain.util.MyMapper
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.apache.ibatis.annotations.Mapper
@Mapper
interface DustDataResultMapper : MyMapper<DustDataResult?>
interface DustDataResultMapper : MyMapper<DustDataResult?> {
    fun selectByArea(areaVo: AreaVo): List<DustDataResult?>
}
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/ProblemlistMapper.kt
@@ -2,6 +2,7 @@
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.util.MyMapper
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import cn.flightfeather.supervision.lightshare.vo.SceneProblemSummary
import cn.flightfeather.supervision.lightshare.vo.StatisticsVo
import cn.flightfeather.supervision.lightshare.vo.UnChangedPro
@@ -13,18 +14,8 @@
    /**
     * èŽ·å–æŸæ—¶é—´æ®µå†…ã€æŸä¸ªåŒºåŽ¿çš„æŸç§åœºæ™¯ä¸‹ï¼Œå„ç±»åž‹çš„é—®é¢˜æ•°é‡ç»Ÿè®¡
     * @param districtCode åŒºåŽ¿è¡Œæ”¿ç¼–ç 
     * @param startTime å¼€å§‹æ—¶é—´
     * @param endTime ç»“束时间
     * @param sceneType åœºæ™¯ç±»åž‹
     */
    fun getStatisticalResult(
        districtCode: String?,
        startTime: String?,
        endTime: String?,
        sceneType: String?,
        sceneId: String?,
    ): List<StatisticsVo>
    fun getStatisticalResult(areaVo: AreaVo): List<StatisticsVo>
    fun getStatisticalResultById(topTaskId: String?, sceneTypeId: String?): List<Map<String, JvmType.Object>>
@@ -59,12 +50,7 @@
    fun getUnChangedProblem(deadLine: String): List<UnChangedPro>
    /**
     * èŽ·å–æ€»ä»»åŠ¡
     * èŽ·å–åœºæ™¯é—®é¢˜ç»Ÿè®¡
     */
    fun getSceneProSummary(
        topTaskId: String,
        sceneTypeId: String?,
        sort: String?,
        sortBy: String,
    ): List<SceneProblemSummary>
    fun getSceneProSummary(areaVo: AreaVo): List<SceneProblemSummary>
}
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/EvaluationRep.kt
@@ -24,14 +24,14 @@
     * @param date æ—¥æœŸï¼Œåªä½¿ç”¨å¹´å’Œæœˆ
     * @return
     */
    fun findByScene(sceneId: String?, date: LocalDate): Evaluation? {
    fun findByScene(sceneId: String?, date: LocalDate): List<Evaluation?> {
        val sT = date.withDayOfMonth(1).atStartOfDay()
        val eT = sT.plusMonths(1).minusSeconds(1)
        val res = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
            createCriteria().andEqualTo("sguid", sceneId)
                .andBetween("evaluatetime", sT, eT)
        })
        return if (res.isNotEmpty()) res[0] else null
        return res
    }
    fun findBySubtask(subTaskId: String?): Evaluation? {
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/MonitorDataRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package cn.flightfeather.supervision.domain.ds1.repository
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
import cn.flightfeather.supervision.domain.ds1.mapper.DustDataResultMapper
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.springframework.stereotype.Repository
/**
 * ç›‘测数据数据库查询
 * @date 2025/3/19
 * @author feiyu02
 */
@Repository
class MonitorDataRep(
    private val dataResultMapper: DustDataResultMapper,
) {
    /**
     * æ ¹æ®è¡Œæ”¿åŒºåŸŸã€æ—¶é—´ã€ä»¥åŠåœºæ™¯ç±»åž‹æŸ¥è¯¢ç»“æžœ
     */
    fun fetchDustDataResult(areaVo: AreaVo): List<DustDataResult?> {
        return dataResultMapper.selectByArea(areaVo)
    }
}
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/ProblemRep.kt
@@ -2,6 +2,7 @@
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.ds1.mapper.ProblemlistMapper
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import cn.flightfeather.supervision.lightshare.vo.SceneProblemSummary
import org.springframework.stereotype.Repository
@@ -17,12 +18,15 @@
        return problemlistMapper.updateByPrimaryKey(problemlist)
    }
    fun find(problemlist: Problemlist): List<Problemlist?> {
        return problemlistMapper.select(problemlist)
    }
    /**
     * èŽ·å–å„åœºæ™¯çš„é—®é¢˜å’Œæ•´æ”¹æ•°é‡ç»Ÿè®¡
     */
    fun selectSceneProSummary(topTaskId: String, sceneTypeId: String?, sort: String?, sortBy: String):
            List<SceneProblemSummary> {
        return problemlistMapper.getSceneProSummary(topTaskId, sceneTypeId, sort, sortBy)
    fun selectSceneProSummary(areaVo: AreaVo): List<SceneProblemSummary> {
        return problemlistMapper.getSceneProSummary(areaVo)
    }
    fun findOne(guid: String?): Problemlist? {
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/repository/TaskRep.kt
@@ -13,16 +13,33 @@
@Repository
class TaskRep(private val taskMapper: TaskMapper, private val monitorobjectversionMapper: MonitorobjectversionMapper) {
    private fun exampleTask(areaVo: AreaVo): Task?{
    private fun exampleTask(areaVo: AreaVo, levelNum: Int? = null): Example? {
        areaVo.starttime ?: return null
        val mStart = areaVo.starttime!!.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0)
        val mEnd = mStart.plusMonths(1).minusSeconds(1)
        return Task().apply {
            provincecode = areaVo.provincecode
            citycode = areaVo.citycode
            districtcode = areaVo.districtcode
            starttime = Date.from(mStart.atZone(ZoneId.systemDefault()).toInstant())
            endtime = Date.from(mEnd.atZone(ZoneId.systemDefault()).toInstant())
//        return Task().apply {
//            provincecode = areaVo.provincecode
//            citycode = areaVo.citycode
//            districtcode = areaVo.districtcode
//            starttime = Date.from(mStart.atZone(ZoneId.systemDefault()).toInstant())
//            endtime = Date.from(mEnd.atZone(ZoneId.systemDefault()).toInstant())
//        }
        return Example(Task::class.java).apply {
            createCriteria()
                .apply {
                    if (levelNum != null) {
                        andEqualTo("levelnum", levelNum)
                    } else {
                        andIsNull("levelnum")
                    }
                }
                .andEqualTo("provincecode", areaVo.provincecode)
                .andEqualTo("citycode", areaVo.citycode)
                .andEqualTo("districtcode", areaVo.districtcode)
                .andGreaterThanOrEqualTo("starttime", mStart)
                .andLessThanOrEqualTo("endtime", mEnd)
            orderBy("starttime")
        }
    }
@@ -34,13 +51,17 @@
     * æŸ¥æ‰¾ä¸€ä¸ªæ€»ä»»åŠ¡
     */
    fun findOneTask(areaVo: AreaVo): Task? {
        val example = exampleTask(areaVo) ?: return null
        return taskMapper.selectOne(example)
        val list = findTasks(areaVo)
        return if (list.isEmpty()) {
            null
        } else {
            list[0]
        }
    }
    fun findTasks(areaVo: AreaVo): List<Task?> {
        val example = exampleTask(areaVo) ?: return emptyList()
        return taskMapper.select(example)
        val example = exampleTask(areaVo, 2) ?: return emptyList()
        return taskMapper.selectByExample(example)
    }
    fun findTasks(task: Task): List<Task?> {
@@ -58,10 +79,13 @@
    /**
     * èŽ·å–æ—¥ä»»åŠ¡
     * @param taskId é¡¶å±‚任务id
     * @param userId æ‰§è¡Œç”¨æˆ·id
     */
    fun findDayTasks(taskId: String?): List<Task?> {
    fun findDayTasks(taskId: String?, userId: String? = null): List<Task?> {
        return taskMapper.selectByExample(Example(Task::class.java).apply {
            createCriteria().andEqualTo("tsguid", taskId)
            createCriteria().andEqualTo("tsguid", taskId).apply {
                userId?.let { andLike("executorguids", "%$it%") }
            }
            orderBy("starttime").desc()
        })
    }
src/main/kotlin/cn/flightfeather/supervision/domain/ds2/repository/OverallEvaluationRep.kt
@@ -5,6 +5,7 @@
import cn.flightfeather.supervision.domain.ds2.entity.OverallEvaluation
import cn.flightfeather.supervision.domain.ds2.mapper.OverallEvaluationMapper
import org.springframework.stereotype.Repository
import tk.mybatis.mapper.entity.Example
import java.time.LocalDate
import java.time.ZoneId
import java.util.*
@@ -13,6 +14,17 @@
class OverallEvaluationRep(private val overallEvaluationMapper: OverallEvaluationMapper){
    /**
     * èŽ·å–æœ€æ–°è®°å½•
     */
    fun selectLatest(userId: String?): OverallEvaluation? {
        val res = overallEvaluationMapper.selectByExample(Example(OverallEvaluation::class.java).apply {
            createCriteria().andEqualTo("biGuid", userId)
            orderBy("oeUpdateTime").desc()
        })
        return if (res.isNotEmpty()) res[0] else null
    }
    /**
     * æ’入一条环信码记录
     * @param userId
     * @param score
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/DomaincatalogService.kt
@@ -1,6 +1,8 @@
package cn.flightfeather.supervision.lightshare.service
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.domain.ds1.entity.Domaincatalog
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import cn.flightfeather.supervision.lightshare.vo.DomaincatalogVo
@@ -16,4 +18,14 @@
    fun update(domaincatalog: Domaincatalog): Int
    fun delete(id: String): Int
    /**
     * å¿«æ·é…ç½®
     * é’ˆå¯¹ä¸€ç§æ–°çš„场景类型,进行快速配置
     */
    fun quickConfiguration(
        target: Constant.SceneType, targetArea: AreaVo, source: Constant.SceneType,
        sourceArea: AreaVo,
    ): Boolean
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/MonitorDataService.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package cn.flightfeather.supervision.lightshare.service
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
import cn.flightfeather.supervision.lightshare.vo.AreaVo
/**
 * ç›‘测数据(包含扬尘监测、油烟监测等等所有监测数据)服务
 * @date 2025/3/19
 * @author feiyu02
 */
interface MonitorDataService {
    fun uploadDustDataResult(dataList: List<DustDataResult>): Boolean
    fun fetchDustDataResult(areaVo: AreaVo): List<DustDataResult?>
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemlistService.kt
@@ -56,6 +56,5 @@
    fun getSceneByProType(areaVo: AreaVo, pType:String):List<Subtask?>
    fun getSceneProSummary(areaVo: AreaVo, sortBy: String, page: Int, per_page: Int): Pair<DataHead?,
            List<SceneProblemSummary>?>
    fun getSceneProSummary(areaVo: AreaVo, page: Int, per_page: Int): Pair<DataHead?, List<SceneProblemSummary>?>
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemtypeService.kt
@@ -1,5 +1,6 @@
package cn.flightfeather.supervision.lightshare.service
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.domain.ds1.entity.Problemtype
import cn.flightfeather.supervision.lightshare.vo.ProblemDetailVo
import cn.flightfeather.supervision.lightshare.vo.ProblemtypeVo
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/TaskService.kt
@@ -30,7 +30,7 @@
    fun getDayTaskList(taskVoList: List<TaskVo>, date: String, guid: String, userType: String): List<TaskVo>
    fun getDayTask(taskId: String, userId: String, userType: String): List<DayTaskProgressVo>
    fun getDayTask(taskId: String, userId: String?, userType: String): List<DayTaskProgressVo>
    fun findByName(name: String): TaskVo
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomaincatalogServiceImpl.kt
@@ -1,14 +1,26 @@
package cn.flightfeather.supervision.lightshare.service.impl
import cn.flightfeather.supervision.domain.ds1.entity.Domaincatalog
import cn.flightfeather.supervision.domain.ds1.mapper.DomaincatalogMapper
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.common.utils.UUIDGenerator
import cn.flightfeather.supervision.domain.ds1.entity.*
import cn.flightfeather.supervision.domain.ds1.mapper.*
import cn.flightfeather.supervision.lightshare.service.DomaincatalogService
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import cn.flightfeather.supervision.lightshare.vo.DomaincatalogVo
import org.springframework.beans.BeanUtils
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import tk.mybatis.mapper.entity.Example
import java.util.*
@Service
class DomaincatalogServiceImpl(val domaincatalogMapper: DomaincatalogMapper) : DomaincatalogService {
class DomaincatalogServiceImpl(
    private val domaincatalogMapper: DomaincatalogMapper,
    private val problemtypeMapper: ProblemtypeMapper,
    private val changeAdviceMapper: ChangeAdviceMapper,
    private val evaluationruleMapper: EvaluationruleMapper,
    private val evaluationsubruleMapper: EvaluationsubruleMapper,
) : DomaincatalogService {
    //根据name查询
    override fun findOneByName(name: String): Domaincatalog? {
        val domaincatalog = Domaincatalog()
@@ -35,4 +47,66 @@
    override fun update(domaincatalog: Domaincatalog): Int = domaincatalogMapper.updateByPrimaryKey(domaincatalog)
    override fun delete(id: String): Int = domaincatalogMapper.deleteByPrimaryKey(id)
    @Transactional
    override fun quickConfiguration(
        target: Constant.SceneType,
        targetArea: AreaVo,
        source: Constant.SceneType,
        sourceArea: AreaVo,
    ): Boolean {
        //1. é—®é¢˜ç±»åž‹å’Œæ•´æ”¹å»ºè®®
        val adviceList = changeAdviceMapper.selectByExample(Example(ChangeAdvice::class.java).apply {
            createCriteria().andEqualTo("adExtension1", sourceArea.districtname)
                .andEqualTo("adExtension2", source.text)
        })
        problemtypeMapper.selectByExample(Example(Problemtype::class.java).apply {
            createCriteria().andEqualTo("scensetypeid", source.value.toByte())
                .andEqualTo("districtname", sourceArea.districtname)
        }).forEach {
            val newProblemGuid = UUIDGenerator.generate16ShortUUID()
            adviceList.find { ad -> ad.adProblemtypeguid == it.guid }?.let { ad ->
                ad.adGuid = UUIDGenerator.generate16ShortUUID()
                ad.adProblemtypeguid = newProblemGuid
                ad.adCreatedate = Date()
                ad.adUpdatedate = Date()
                ad.adExtension1 = targetArea.districtname
                ad.adExtension2 = target.text
                changeAdviceMapper.insert(ad)
            }
            it.guid = newProblemGuid
            it.scensetypeid = target.value.toByte()
            it.scensetype = target.text
            it.createdate = Date()
            it.updatedate = Date()
            it.provincecode = targetArea.provincecode
            it.provincename = targetArea.provincename
            it.citycode = targetArea.citycode
            it.cityname = targetArea.cityname
            it.districtcode = targetArea.districtcode
            it.districtname = targetArea.districtname
            problemtypeMapper.insert(it)
        }
        return true
        //2. é—®é¢˜ä½ç½®ï¼ˆé»˜è®¤å·¥åœ°ï¼Œå¯ä¸ä¿®æ”¹ï¼‰
        //3. è‡ªè¯„规则表
//        evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
//            createCriteria().andEqualTo("tasktypeid", 99)
//                .andEqualTo("scensetypeid", source.value)
//            and(createCriteria().orEqualTo("provincecode", sourceArea.provincecode).orIsNull("provincecode"))
//            and(createCriteria().orEqualTo("citycode", sourceArea.citycode).orIsNull("citycode"))
//            and(createCriteria().orEqualTo("districtcode", sourceArea.districtcode).orIsNull("districtcode"))
//            and(createCriteria().orEqualTo("towncode", sourceArea.towncode).orIsNull("towncode"))
//        }).takeIf { it.isNotEmpty() }?.get(0).let {sourceRule ->
//            if (sourceRule != null) {
//                evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule::class.java).apply {
//                    createCriteria().andEqualTo("", sourceRule)
//                })
//            }
//        }
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/MonitorDataServiceImpl.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package cn.flightfeather.supervision.lightshare.service.impl
import cn.flightfeather.supervision.business.autooutput.AopOutput
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
import cn.flightfeather.supervision.domain.ds1.repository.MonitorDataRep
import cn.flightfeather.supervision.lightshare.service.MonitorDataService
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
/**
 *
 * @date 2025/3/19
 * @author feiyu02
 */
@Service
class MonitorDataServiceImpl(
    private val aopOutput: AopOutput,
    private val monitorDataRep: MonitorDataRep,
) : MonitorDataService {
    @Transactional
    override fun uploadDustDataResult(dataList: List<DustDataResult>): Boolean {
        dataList.forEach { aopOutput.toDbDataResult(it) }
        return true
    }
    override fun fetchDustDataResult(areaVo: AreaVo): List<DustDataResult?> {
        return monitorDataRep.fetchDustDataResult(areaVo)
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemlistServiceImpl.kt
@@ -130,11 +130,11 @@
    //根据区县、场景类型、时间获取各个问题数量
    override fun getStatisticalResult(areaVo: AreaVo): List<StatisticsVo> {
        val districtcode = areaVo.districtcode
        val sceneType = areaVo.scensetypeid
        val startTime = areaVo.starttime?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        val endTime = areaVo.endtime?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        return problemlistMapper.getStatisticalResult(districtcode, startTime, endTime, sceneType, areaVo.sceneId)
//        val districtcode = areaVo.districtcode
//        val sceneType = areaVo.scensetypeid
//        val startTime = areaVo.starttime?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
//        val endTime = areaVo.endtime?.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        return problemlistMapper.getStatisticalResult(areaVo)
    }
    override fun getChargeResult(areaVo: AreaVo): ChargeInfoVo {
@@ -373,7 +373,7 @@
        userId: String,
        userName: String,
    ): BaseResponse<String> {
        if (action !in 0..3) {
        if (action !in 0..5) {
            return BaseResponse(false, "非法的操作指令")
        }
        val p = problemlistMapper.selectByPrimaryKey(pId) ?: return BaseResponse(false, "问题不存在")
@@ -398,6 +398,14 @@
                        response.success = false
                        response.message = "问题提交还未审核,无法进行整改审核!"
                    }
                    4.toByte() -> {
                        response.success = false
                        response.message = "问题提交还未审核,无法进行撤回审核!"
                    }
                    5.toByte() -> {
                        response.success = false
                        response.message = "问题整改还未提交,无法进行撤回审核!"
                    }
                }
            } else if (extension3 == Constant.PROBLEM_CHECK_PASS || extension3 == Constant.PROBLEM_CHECK_FAIL) {
                when (action) {
@@ -419,6 +427,13 @@
                            response.message = "问题还未整改,无法进行整改审核!操作无效"
                        }
                    }
                    4.toByte() -> {
                        extension3 = Constant.PROBLEM_UNCHECKED
                    }
                    5.toByte() -> {
                        response.success = false
                        response.message = "问题整改还未审核,无法进行整改审核撤回操作!操作无效"
                    }
                }
            } else if (extension3 == Constant.CHANGE_UNCHECKED) {
                event = "在${subtask?.scensename}审核了一个整改"
@@ -431,6 +446,14 @@
                    }
                    2.toByte() -> extension3 = Constant.CHANGE_CHECK_PASS
                    3.toByte() -> extension3 = Constant.CHANGE_CHECK_FAIL
                    4.toByte() -> {
                        response.success = false
                        response.message = "问题整改还未审核,无法进行撤回审核!"
                    }
                    5.toByte() -> {
                        response.success = false
                        response.message = "问题提交已审核,并且已被整改。操作无效"
                    }
                }
            } else if (extension3 == Constant.CHANGE_CHECK_PASS || extension3 == Constant.CHANGE_CHECK_FAIL) {
                when (action) {
@@ -442,6 +465,13 @@
                    }
                    2.toByte() -> extension3 = Constant.CHANGE_CHECK_PASS
                    3.toByte() -> extension3 = Constant.CHANGE_CHECK_FAIL
                    4.toByte() -> {
                        response.success = false
                        response.message = "问题提交已审核,并且已被整改,无法进行问题审核撤销操作。操作无效"
                    }
                    5.toByte() -> {
                        extension3 = Constant.CHANGE_UNCHECKED
                    }
                }
            }
        }
@@ -495,6 +525,7 @@
        mediafileService.deleteList(deleteImg)
        return "success"
    }
    override fun changeProblem(problemId: String, files: Array<MultipartFile>): BaseResponse<String> {
        // é—®é¢˜å’Œé—®é¢˜å›¾ç‰‡åˆæ³•性检查
@@ -595,14 +626,13 @@
    override fun getSceneProSummary(
        areaVo: AreaVo,
        sortBy: String,
        page: Int,
        per_page: Int,
    ): Pair<DataHead?, List<SceneProblemSummary>?> {
        areaVo.scensetypeid ?: throw BizException("缺少场景类型参数")
        val task = taskRep.findOneTask(areaVo) ?: throw BizException("未找到对应的巡查总任务")
//        areaVo.scensetypeid ?: throw BizException("缺少场景类型参数")
//        val task = taskRep.findOneTask(areaVo) ?: throw BizException("未找到对应的巡查总任务")
        val p = PageHelper.startPage<SceneProblemSummary>(page, per_page)
        val res = problemRep.selectSceneProSummary(task.tguid!!, areaVo.scensetypeid!!, areaVo.sort, sortBy)
        val res = problemRep.selectSceneProSummary(areaVo)
        return DataHead(p.pageNum, p.pages, p.total) to res
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemtypeServiceImpl.kt
@@ -1,5 +1,7 @@
package cn.flightfeather.supervision.lightshare.service.impl
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.common.utils.UUIDGenerator
import cn.flightfeather.supervision.domain.ds1.entity.Problemtype
import cn.flightfeather.supervision.domain.ds1.mapper.ProblemtypeMapper
import cn.flightfeather.supervision.lightshare.service.ProblemtypeService
@@ -7,8 +9,10 @@
import cn.flightfeather.supervision.lightshare.vo.ProblemtypeVo
import org.springframework.beans.BeanUtils
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import tk.mybatis.mapper.entity.Example
import tk.mybatis.mapper.util.StringUtil
import java.util.*
@Service
class ProblemtypeServiceImpl(val problemtypeMapper: ProblemtypeMapper) : ProblemtypeService {
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SubtaskServiceImpl.kt
@@ -946,7 +946,8 @@
                districtName = t.districtname
                townCode = t.towncode
                townName = t.townname
                subTaskSummary = subtaskMapper.getSummary(t.tguid!!, areaVo.scensetypeid?.toIntOrNull())
                areaVo.topTaskId = t.tguid
                subTaskSummary = subTaskRep.findSummary(areaVo)
            }
            res.add(pro)
        }
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/TaskServiceImpl.kt
@@ -318,55 +318,64 @@
        return taskVoList
    }
    override fun getDayTask(taskId: String, userId: String, userType: String): List<DayTaskProgressVo> {
        val example = Example(Task::class.java)
        val criteria = example.createCriteria()
        //构造查询条件
        criteria.andEqualTo("tsguid", taskId)
        if (userType == "1") {
            criteria.andLike("executorguids", "%$userId%")
        }
    override fun getDayTask(taskId: String, userId: String?, userType: String): List<DayTaskProgressVo> {
        val resultList = ArrayList<DayTaskProgressVo>()
        // èŽ·å–æ€»ä»»åŠ¡ä¸‹æ‰€æœ‰æ—¥ä»»åŠ¡
        val dayTasks = if (userType == "1") {
            taskRep.findDayTasks(taskId, userId)
        } else {
            taskRep.findDayTasks(taskId)
        }
        // èŽ·å–æ€»ä»»åŠ¡ä¸‹æ‰€æœ‰çš„å­ä»»åŠ¡
        val subTasks = subTaskRep.findAll(Subtask().apply { tguid = taskId })
        //根据sql条件查询
        taskMapper.selectByExample(example).forEach {
            val exampleTotal = Example(Subtask::class.java).apply {
                createCriteria().andEqualTo("tsguid", it.tguid)
        dayTasks.forEach {t->
            // ç­›é€‰å½“前日任务下的子任务
            val filterSubTasks = subTasks.filter {s->
                s?.tsguid == t?.tguid
            }
            // å­ä»»åŠ¡æ€»æ•°
            val total = filterSubTasks.size
            // å­ä»»åŠ¡å®Œæˆæ•°
            val complete = filterSubTasks.count {fs->
                fs?.status == Constant.TaskProgress.RUNINGSTATUS3.text
            }
            val total = subtaskMapper.selectCountByExample(exampleTotal)
            val exampleComplete = exampleTotal.apply {
                and().andEqualTo("status", Constant.TaskProgress.RUNINGSTATUS3.text)
            // èŽ·å–å½“æ—¥æ‰€æœ‰çš„é—®é¢˜
            val subTaskIds = filterSubTasks.map { fs-> fs?.stguid }
            val problemList = if (subTaskIds.isNotEmpty()) {
                problemListMapper.selectByExample(Example(Problemlist::class.java).apply {
                    createCriteria().andIn("stguid", subTaskIds)
                })
            } else{
                emptyList()
            }
            val complete = subtaskMapper.selectCountByExample(exampleComplete)
            var changed = 0
            problemListMapper.findUnchangedCount(it.tguid ?: "").forEach { i ->
                //结果表示该子任务未整改问题数
                if (i == 0) {
                    changed++
                }
            }
            //审核是否完成
            var check = false
            with(subtaskMapper.selectByExample(exampleTotal)) breaking@{
                forEach {
                    problemListMapper.selectByExample(Example(Problemlist::class.java).apply {
                        createCriteria().andEqualTo("stguid", it.stguid)
                    }).forEach { problem ->
                        if (problem.extension3 == Constant.PROBLEM_UNCHECKED) {
                            check = true
                            return@breaking
                        }
            var check = true
            filterSubTasks.forEach {fs ->
                // ç­›é€‰æ¯ä¸ªå­ä»»åŠ¡ä¸‹çš„é—®é¢˜æœªæ•´æ”¹æ•°
                problemList.filter { p-> p?.stguid == fs?.stguid }.onEach { pro ->
                    // å½“存在至少一个问题没有审核时,当日审核状态为未审核
                    if (pro.extension3 == Constant.PROBLEM_UNCHECKED || pro.extension3 == Constant.CHANGE_UNCHECKED) {
                        check = false
                    }
                }.count { i -> i?.ischanged != true }.let { c ->
                    // æ²¡æœ‰æœªæ•´æ”¹é—®é¢˜æ—¶ï¼Œåˆ™è¡¨ç¤ºè¯¥å­ä»»åŠ¡å·²ç»æ•´æ”¹å®Œæˆ
                    if (c == 0) {
                        changed++
                    }
                }
            }
            resultList.add(DayTaskProgressVo(
                it.tguid, it.starttime, taskId, complete, changed, total, check
                t?.tguid, t?.starttime, taskId, complete, changed, total, check
            ))
        }
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/AreaVo.kt
@@ -12,6 +12,9 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("区域条件")
open class AreaVo {
    @ApiModelProperty("总任务id")
    var topTaskId: String? = null
    @ApiModelProperty("省份编码")
    var provincecode: String? = null
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/BaseResPack.kt
@@ -22,5 +22,9 @@
        }
    } catch (e: BizException) {
        BaseResponse(false, message = e.message ?: "")
    } catch (e: Exception) {
        // fixme: to log system
        BaseResponse(false, message = "服务器出现内部错误")
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/MonitorDataController.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package cn.flightfeather.supervision.lightshare.web
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
import cn.flightfeather.supervision.lightshare.service.MonitorDataService
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
/**
 * ç›‘测数据(包含扬尘监测、油烟监测等等所有监测数据)相关API接口
 * @date 2025/3/19
 * @author feiyu02
 */
@Api(tags = ["MonitorDataController"], description = "监测数据(包含扬尘监测、油烟监测等等所有监测数据)相关API接口")
@RestController
@RequestMapping("/monitor/data")
class MonitorDataController(private val monitorDataService: MonitorDataService) {
    @ApiOperation(value = "上传扬尘监测数据的月度统计结果")
    @PutMapping("/result/construction/upload")
    fun uploadDustDataResult(
        @ApiParam("统计结果") @RequestBody dataList: List<DustDataResult>,
    ) = resPack { monitorDataService.uploadDustDataResult(dataList) }
    @ApiOperation(value = "查询扬尘监测数据的月度统计结果")
    @PostMapping("/result/construction/get")
    fun fetchDustDataResult(
        @ApiParam("区域条件信息") @RequestBody areaVo: AreaVo
    ) = resPack { monitorDataService.fetchDustDataResult(areaVo) }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ProblemlistController.kt
@@ -88,8 +88,8 @@
    @PostMapping("/check")
    fun checkProblem(
        @ApiParam(value = "问题id主键") @RequestParam("pId") pId: String,
        @ApiParam(value = "审核操作, 0: å®¡æ ¸é€šè¿‡ï¼›1: å®¡æ ¸ä¸é€šè¿‡ï¼›2: æ•´æ”¹é€šè¿‡ï¼›3: æ•´æ”¹ä¸é€šè¿‡",
            allowableValues = "0,1,2,3") @RequestParam("action") action: Byte,
        @ApiParam(value = "审核操作, 0: å®¡æ ¸é€šè¿‡ï¼›1: å®¡æ ¸ä¸é€šè¿‡ï¼›2: æ•´æ”¹é€šè¿‡ï¼›3: æ•´æ”¹ä¸é€šè¿‡ï¼›4:问题审核撤回;5:整改审核撤回",
            allowableValues = "0,1,2,3,4,5") @RequestParam("action") action: Byte,
        @ApiParam(value = "审核备注") @RequestParam("remark") remark: String,
        @ApiParam(value = "用户id") @RequestParam("userId") userId: String,
        @ApiParam(value = "用户名") @RequestParam("userName") userName: String,
@@ -146,8 +146,7 @@
    @PostMapping("/summary/scene")
    fun getSceneProSummary(
        @RequestBody areaVo: AreaVo,
        @ApiParam(value = "排序字段", allowableValues = "pro, changePer") @RequestParam sortBy: String,
        @ApiParam(value = "页码") @RequestParam(value = "page") page: Int,
        @ApiParam(value = "单页数据量") @RequestParam(value = "per_page") perPage: Int,
    ) = resPack { problemlistService.getSceneProSummary(areaVo, sortBy, page, perPage) }
    ) = resPack { problemlistService.getSceneProSummary(areaVo, page, perPage) }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/TaskController.kt
@@ -52,7 +52,7 @@
    @GetMapping("/dayTask/{taskId}")
    fun getDayTask(
            @PathVariable("taskId") taskId: String,
            @RequestParam("userId") userId: String,
            @RequestParam("userId", required = false) userId: String?,
            @RequestParam("userType") userType: String
    ) = taskService.getDayTask(taskId, userId, userType)
src/main/kotlin/cn/flightfeather/supervision/socket/LocalDateTimeAdapter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package cn.flightfeather.supervision.socket;
import com.google.gson.*;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * LocalDateTime类型的时间格式序列化和反序列化类
 * by hc 2024.12.6
 */
public class LocalDateTimeAdapter implements JsonDeserializer<LocalDateTime>, JsonSerializer<LocalDateTime> {
    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @Override
    public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(dateTimeFormatter.format(src));
    }
    @Override
    public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try {
            return LocalDateTime.parse(json.getAsString(), dateTimeFormatter);
        } catch (Exception e) {
            throw new JsonParseException(e);
        }
    }
}
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketMessage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package cn.flightfeather.supervision.socket;
public class WebSocketMessage {
    /*
    * æ¶ˆæ¯ç±»åž‹
    * */
    private int type;
    /*
    * æ¶ˆæ¯å†…容
    * */
    private Object content;
    public WebSocketMessage() {
    }
    public WebSocketMessage(int type, Object content) {
        this.type = type;
        this.content = content;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public Object getContent() {
        return content;
    }
    public void setContent(Object content) {
        this.content = content;
    }
}
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketMessageParser.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package cn.flightfeather.supervision.socket;
import cn.flightfeather.supervision.common.utils.JsonUtil;
import org.springframework.util.StringUtils;
public class WebSocketMessageParser {
    private static final String START_STR = "##";
    private static final String SPLIT_STR = "&&";
    private static final String END_STR = "%%";
    /**
     * æ¶ˆæ¯æ ¼å¼æ ¡éªŒ
     * @param message æ¶ˆæ¯
     * @return æ ¼å¼æ˜¯å¦åˆè§„
     */
    private static boolean verificationMessage(String message) {
        if (StringUtils.isEmpty(message)) {
            return false;
        }
        if (!message.startsWith(START_STR)) {
            return false;
        }
        if (!message.endsWith(END_STR)) {
            return false;
        }
        return true;
    }
    /**
     * è§£æžå‡ºç±»åž‹å’Œå†…容
     * @param message socket消息中的data字段
     * @return è§£æžç»“果,如果格式不正确则返回null
     */
    public static WebSocketMessage decodeMessage(String message) {
        if (!verificationMessage(message)) {
            // å‘挥一个不会被处理的消息
            return new WebSocketMessage(-1, "");
        }
        WebSocketMessage webSocketMessage = new WebSocketMessage();
        String[] parts = message.substring(START_STR.length(), message.length() - END_STR.length()).split(SPLIT_STR);
        webSocketMessage.setType(Integer.parseInt(parts[0]));
        webSocketMessage.setContent(JsonUtil.INSTANCE.getGson().fromJson(parts[1], Object.class));
        return webSocketMessage;
    }
    /**
     * ç”ŸæˆæŒ‡å®šæ ¼å¼çš„æ¶ˆæ¯å­—符串
     * @return ç”Ÿæˆçš„æ¶ˆæ¯å­—符串
     */
    public static String encodeMessage(WebSocketMessage webSocketMessage) {
        return START_STR + webSocketMessage.getType() + SPLIT_STR + JsonUtil.INSTANCE.getGson().toJson(webSocketMessage.getContent(), webSocketMessage.getContent().getClass()) + END_STR;
    }
}
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketSendMessageUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package cn.flightfeather.supervision.socket;
import cn.flightfeather.supervision.common.executor.BgTaskStatus;
import cn.flightfeather.supervision.common.utils.Constant;
public class WebSocketSendMessageUtil {
    /**
     * å‘送后台任务的socket消息
     * @param bgTaskStatus æ¶ˆæ¯çš„内容
     */
    public static void sendBgTaskMessage(BgTaskStatus bgTaskStatus) {
        WebSocketMessage webSocketMessage = new WebSocketMessage(Constant.SocketMessageType.BG_TASK.getValue(),
                bgTaskStatus);
        String message = WebSocketMessageParser.encodeMessage(webSocketMessage);
        WebSocketSenderHandler.getInstance().broadcast(message);
    }
}
src/main/kotlin/cn/flightfeather/supervision/socket/WebSocketSenderHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package cn.flightfeather.supervision.socket;
import cn.flightfeather.supervision.socket.processor.WebSocketSender;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class WebSocketSenderHandler implements ApplicationContextAware {
    static private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        WebSocketSenderHandler.applicationContext = applicationContext;
    }
    public static WebSocketSender getInstance() {
        return applicationContext.getBean(WebSocketSender.class);
    }
}
src/main/kotlin/cn/flightfeather/supervision/socket/config/SPTextWebSocketHandler.kt
@@ -1,5 +1,7 @@
package cn.flightfeather.supervision.socket.config
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.socket.WebSocketMessageParser
import cn.flightfeather.supervision.socket.WsSessionManager
import cn.flightfeather.supervision.socket.processor.WebSocketReceiver
import org.springframework.stereotype.Component
@@ -45,6 +47,10 @@
        val payload = message.payload
        val sessionId = session.attributes["session_id"]
        println("server æŽ¥æ”¶åˆ° $sessionId å‘送的 $payload")
        if (WebSocketMessageParser.decodeMessage(payload).type ==
            Constant.SocketHeartMessageType.HEART_MESSAGE_TYPE.value) {
            webSocketReceiver.onReceiveHeartMsg(payload, sessionId.toString())
        }
        webSocketReceiver.onReceiveMsg(payload)
//        session.sendMessage(TextMessage("server å‘送给 " + sessionId + " æ¶ˆæ¯ " + payload + " " + LocalDateTime.now()
//            .toString()))
src/main/kotlin/cn/flightfeather/supervision/socket/processor/WebSocketReceiver.kt
@@ -2,7 +2,11 @@
import cn.flightfeather.supervision.common.log.BizLog
import cn.flightfeather.supervision.common.log.WorkStreamLogInfo
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.socket.WebSocketMessage
import cn.flightfeather.supervision.socket.WebSocketMessageParser
import org.springframework.stereotype.Component
import java.time.LocalDateTime
/**
 * webSocket消息接收管理
@@ -10,7 +14,7 @@
 * @author feiyu02
 */
@Component
class WebSocketReceiver(private val bizLog: BizLog) {
class WebSocketReceiver(private val bizLog: BizLog, private val webSocketSender: WebSocketSender) {
    /**
     * æŽ¥æ”¶æ¶ˆæ¯å¤„理
@@ -21,4 +25,13 @@
            bizLog.info(WorkStreamLogInfo("8FAqSPnAA8ry4ExX", "朱正强", "在上海广发粉煤灰有限公司新增一个问题"))
        }
    }
    /**
     * æŽ¥æ”¶å¿ƒè·³æ¶ˆæ¯å¤„理
     */
    fun onReceiveHeartMsg(msg: String, sessionId: String) {
        val content = WebSocketMessageParser.encodeMessage(WebSocketMessage(Constant.SocketHeartMessageType.HEART_MESSAGE_TYPE.value,
            LocalDateTime.now()))
        webSocketSender.sendMsg(content, sessionId)
    }
}
src/main/resources/mapper/ds1/DustDataResultMapper.xml
@@ -25,4 +25,33 @@
    DR_Id, DR_Scene_Id, DR_Scene_Name, DR_Device_Code, DR_Time, DR_Exceed_Times, DR_Avg, 
    DR_Max, DR_Min, DR_Over_Avg_Per, DR_Data_Num, DR_Effective_Rate
  </sql>
  <!-- æ•°æ®ç»Ÿè®¡ç»“果时间条件 -->
  <sql id="Where_Plan_Time">
    <if test="starttime != null">
      AND ${tableAlias}.DR_Time >= #{starttime}
    </if>
    <if test="endtime != null">
      AND ${tableAlias}.DR_Time &lt;= #{endtime}
    </if>
  </sql>
  <select id="selectByArea" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from ea_t_dust_data_result as a
    left join sm_t_scense as b
    on a.DR_Scene_Id = b.S_GUID
    <where>
      <include refid="cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper.Where_Area">
        <property name="tableAlias" value="b"/>
      </include>
      <include refid="cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper.Where_Type">
        <property name="tableAlias" value="b"/>
      </include>
      <include refid="Where_Plan_Time">
        <property name="tableAlias" value="a"/>
      </include>
    </where>
  </select>
</mapper>
src/main/resources/mapper/ds1/ProblemlistMapper.xml
@@ -76,21 +76,27 @@
        LEFT JOIN sm_t_scense AS f ON a.S_GUID = f.S_GUID
        LEFT JOIN tm_t_subtask AS c ON a.ST_GUID = c.ST_GUID
        <where>
        <if test="startTime != null">
            AND c.ST_PlanStartTime >= #{startTime}
        </if>
        <if test="endTime != null">
            AND c.ST_PlanStartTime &lt;= #{endTime}
        </if>
        <if test="districtCode != null">
            AND f.S_DistrictCode = #{districtCode}
        </if>
        <if test="sceneType != null">
            AND f.S_TypeID = #{sceneType}
        </if>
        <if test="sceneId != null">
            AND a.S_GUID = #{sceneId}
        </if>
<!--        <if test="startTime != null">-->
<!--            AND c.ST_PlanStartTime >= #{startTime}-->
<!--        </if>-->
<!--        <if test="endTime != null">-->
<!--            AND c.ST_PlanStartTime &lt;= #{endTime}-->
<!--        </if>-->
<!--        <if test="districtCode != null">-->
<!--            AND f.S_DistrictCode = #{districtCode}-->
<!--        </if>-->
            <if test="scensetypeid != null">
                AND f.S_TypeID = #{scensetypeid}
            </if>
            <if test="sceneId != null">
                AND a.S_GUID = #{sceneId}
            </if>
            <include refid="cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper.Where_Area">
                <property name="tableAlias" value="f"/>
            </include>
            <include refid="cn.flightfeather.supervision.domain.ds1.mapper.SubtaskMapper.Where_Plan_Time">
                <property name="tableAlias" value="c"/>
            </include>
        </where>
        GROUP BY
        b.PT_TypeName
@@ -214,11 +220,18 @@
            sm_t_scense AS b
            LEFT JOIN tm_t_subtask AS a ON a.ST_ScenseID = b.S_GUID
            LEFT JOIN im_t_problemlist AS d ON a.ST_GUID = d.ST_GUID
            WHERE
            a.T_GUID = #{topTaskId}
            <if test="sceneTypeId != null">
                and b.S_TypeID = #{sceneTypeId}
            </if>
            <where>
                <include refid="cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper.Where_Area">
                    <property name="tableAlias" value="b"/>
                </include>
                <include refid="cn.flightfeather.supervision.domain.ds1.mapper.SubtaskMapper.Where_Plan_Time">
                    <property name="tableAlias" value="a"/>
                </include>
<!--            a.T_GUID = #{topTaskId}-->
                <if test="scensetypeid != null">
                    and b.S_TypeID = #{scensetypeid}
                </if>
            </where>
            GROUP BY
            b.S_GUID
        ) as t_p
src/main/resources/mapper/ds1/ScenseMapper.xml
@@ -42,6 +42,41 @@
    S_Contacts, S_CreateDate, S_UpdateDate, S_Extension1, S_Extension2, S_Index, S_Remark
  </sql>
  <!-- è¡Œæ”¿åŒºåˆ’条件 -->
  <sql id="Where_Area">
    <if test="provincecode != null">
      AND ${tableAlias}.S_ProvinceCode = #{provincecode}
    </if>
    <if test="provincename != null">
      AND ${tableAlias}.S_ProvinceName = #{provincename}
    </if>
    <if test="citycode != null">
      AND ${tableAlias}.S_CityCode = #{citycode}
    </if>
    <if test="cityname != null">
      AND ${tableAlias}.S_CityName = #{cityname}
    </if>
    <if test="districtcode != null">
      AND ${tableAlias}.S_DistrictCode = #{districtcode}
    </if>
    <if test="districtname != null">
      AND ${tableAlias}.S_DistrictName = #{districtname}
    </if>
    <if test="towncode != null">
      AND ${tableAlias}.S_TownCode = #{towncode}
    </if>
    <if test="townname != null">
      AND ${tableAlias}.S_TownName = #{townname}
    </if>
  </sql>
  <!-- åœºæ™¯ç±»åž‹æ¡ä»¶ -->
  <sql id="Where_Type">
    <if test="scensetypeid != null">
      AND ${tableAlias}.S_TypeID = #{scensetypeid}
    </if>
  </sql>
  <select id="selectNoAccountScene" resultMap="BaseResultMap">
    select a.* FROM sm_t_scense as a LEFT JOIN sm_t_userinfo as b on a.S_GUID = b.D_GUID WHERE b.UI_GUID is null
  </select>
src/main/resources/mapper/ds1/SubtaskMapper.xml
@@ -403,12 +403,18 @@
    <select id="getSummaryByArea" resultMap="SubTaskSummary">
        <include refid="Sub_Task_Summary_Column_List"/>
        <where>
            <include refid="Where_Area">
                <property name="tableAlias" value="a"/>
            <include refid="cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper.Where_Area">
                <property name="tableAlias" value="b"/>
            </include>
            <include refid="Where_Plan_Time">
                <property name="tableAlias" value="a"/>
            </include>
            <if test="scensetypeid != null">
                AND b.S_TypeID = #{scensetypeid}
            </if>
            <if test="topTaskId != null">
                AND a.T_GUID = #{topTaskId}
            </if>
        </where>
        GROUP BY
        a.ST_GUID
src/test/kotlin/cn/flightfeather/supervision/business/autooutput/AopEvaluationTest.kt
@@ -79,11 +79,11 @@
     */
    @Test
    fun test() {
        val taskId = "88wgq9l5gm9cUMg1"
        val districtCode = "310104"
//        val taskId = "88wgq9l5gm9cUMg1"
//        val districtCode = "310104"
        val districtName = "徐汇区"
        val year = 2024
        val month = 5
        val month = 11
        val sceneType = Constant.SceneType.TYPE5.value.toInt()
//        xhFuDataAnalysis.setResource(taskId, sceneType, year, month)
//        xhFuDataAnalysis.execute()
src/test/kotlin/cn/flightfeather/supervision/business/crosstimechange/CrossTimeChangeManagerTest.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package cn.flightfeather.supervision.business.crosstimechange
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.junit.Test
import org.junit.jupiter.api.Assertions.*
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.LocalDateTime
@RunWith(SpringRunner::class)
@ExtendWith(SpringExtension::class)
@SpringBootTest
class CrossTimeChangeManagerTest {
    @Autowired
    lateinit var crossTimeChangeManager: CrossTimeChangeManager
    @Test
    fun execute() {
//        crossTimeChangeManager.execute(AreaVo().apply {
//            provincecode = "31"
//            citycode = "3100"
//            districtcode = "310104"
//            starttime = LocalDateTime.of(2024, 3, 1, 0, 0, 0, 0)
//            endtime = LocalDateTime.of(2024, 6, 30, 23, 59, 59, 999)
//            scensetypeid = Constant.SceneType.TYPE5.value
//        }, "徐汇餐饮历史问题可整改统计-3至6月.xlsx")
        crossTimeChangeManager.execute(AreaVo().apply {
            provincecode = "31"
            citycode = "3100"
            districtcode = "310104"
            starttime = LocalDateTime.of(2024, 7, 1, 0, 0, 0, 0)
            endtime = LocalDateTime.of(2024, 10, 31, 23, 59, 59, 999)
            scensetypeid = Constant.SceneType.TYPE5.value
        }, "徐汇餐饮历史问题可整改统计-7至10月.xlsx")
    }
}
src/test/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomaincatalogServiceImplTest.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package cn.flightfeather.supervision.lightshare.service.impl
import cn.flightfeather.supervision.SupervisionApplication
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.lightshare.service.DomaincatalogService
import cn.flightfeather.supervision.lightshare.vo.AreaVo
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest(classes = [SupervisionApplication::class])
class DomaincatalogServiceImplTest {
    @Autowired
    lateinit var domaincatalogService: DomaincatalogService
    @Test
    fun quickConfiguration() {
        domaincatalogService.quickConfiguration(
            Constant.SceneType.TYPE15, AreaVo().apply {
                provincecode = "31"
                provincename = "上海市"
                citycode = "3100"
                cityname = "上海市"
                districtcode = "310105"
                districtname = "长宁区"
            },
            Constant.SceneType.TYPE1, AreaVo().apply {
                provincecode = "31"
                provincename = "上海市"
                citycode = "3100"
                cityname = "上海市"
                districtcode = "310105"
                districtname = "长宁区"
            }
        )
    }
}