feiyu02
2025-10-30 9cb8d7e0f4ffca386b14a15f8a0aca4d1db23252
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package cn.flightfeather.supervision.lightshare.service.impl
 
import cn.flightfeather.supervision.business.autooutput.datasource.AopDbMapper
import cn.flightfeather.supervision.common.utils.QueryByCache
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.ds1.entity.Problemtype
import cn.flightfeather.supervision.domain.ds1.entity.Subtask
import cn.flightfeather.supervision.lightshare.service.DataProdSingleSceneService
import cn.flightfeather.supervision.lightshare.vo.ProblemListVo
import cn.flightfeather.supervision.lightshare.vo.dataprod.DPChangeInfo
import cn.flightfeather.supervision.lightshare.vo.dataprod.DPProblemRecurrence
import cn.flightfeather.supervision.lightshare.vo.dataprod.QueryOptSingle
import cn.flightfeather.supervision.lightshare.vo.dataprod.base.DPInspectionInfo
import org.springframework.beans.BeanUtils
import org.springframework.stereotype.Service
import tk.mybatis.mapper.entity.Example
 
/**
 * 单场景纵向数据统计产品服务实现类
 * @date 2025/10/30
 * @author feiyu02
 */
@Service
class DataProdSingleSceneServiceImpl(private val aopDbMapper: AopDbMapper) : DataProdSingleSceneService {
 
    // 整改要求最大耗时(天)
    private val maxChangeTime = 3
 
    override fun getChangeInfo(option: QueryOptSingle): DPChangeInfo {
        return QueryByCache.queryCache(
            cache = { return@queryCache null },
            calculate = {
                val subtaskList = aopDbMapper.subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                    createCriteria().andEqualTo("scenseid", option.sceneId)
                        .andBetween("planstarttime", option.startTime, option.endTime)
                    orderBy("planstarttime").desc()
                })
                if (subtaskList.isEmpty()) return@queryCache DPChangeInfo()
                val problemList = aopDbMapper.problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                    createCriteria().andIn("stguid", subtaskList.map { it.stguid })
                })
                return@queryCache DPChangeInfo().apply {
                    subTasks = subtaskList
                    problems = problemList.map {problem ->
                        val problemListVo = ProblemListVo()
                        BeanUtils.copyProperties(problem, problemListVo)
                        problemListVo
                    }
                    proCount = problemList.size
                    changeCount = problemList.count { it.ischanged == true }
                    changePer = if (proCount == 0) 0.0 else changeCount.toDouble() / proCount
                    changeTime = problemList
                        .filter { it.ischanged == true }
                        .maxOf { (it.changedtime?.time?:0L) - (it?.time?.time?:0L) }.toInt()
                        .div(1000 * 60 * 60 * 24)
 
                    val eff = if (changeTime == 0) 1.0 else maxChangeTime.toDouble() / changeTime
                    changeEfficiency = if (eff > 1.0) 1.0 else eff
                }
            }
        )
    }
 
    override fun getChangeInfoList(options: List<QueryOptSingle>): List<DPChangeInfo> {
        return options.map { getChangeInfo(it) }
    }
 
    override fun getProblemRecurrence(option: QueryOptSingle): List<DPProblemRecurrence> {
        return QueryByCache.queryCache(
            cache = { return@queryCache null },
            calculate = {
                val problemList = aopDbMapper.problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                    createCriteria().andEqualTo("scenseid", option.sceneId)
                        .andBetween("planstarttime", option.startTime, option.endTime)
                    orderBy("planstarttime").desc()
                })
                if (problemList.isEmpty()) return@queryCache emptyList()
                val problemTypeList = aopDbMapper.problemtypeMapper.selectByExample(Example(Problemtype::class.java)
                    .apply { createCriteria().andIn("guid", problemList.map { it.ptguid }) })
 
                val problemMap = problemList
                    .filter {
                        val type = problemTypeList.find { type-> type.guid == it.ptguid }
                        type?.typename != "道路扬尘" || type.description == "工地内多条道路明显泥痕/泥泞/积尘/遗撒"
                    }.groupBy { problem ->
                    val type = problemTypeList.find { type-> type.guid == problem.ptguid } ?: return@groupBy null
                    /**
                     * 2025.10.30 目前根据业务要求,在工地类型中,“道路扬尘”问题出现概率非常高,
                     * 因此该问题在做重复性统计时, 只统计用其子类型"工地内多条道路明显泥痕/泥泞/积尘/遗撒"为分类类型
                     */
                    if (type.typename == "道路扬尘") {
                        type.description
                    } else {
                        type.typename
                    }
                }
                return@queryCache problemMap.map { (key, value) ->
                    val type = problemTypeList.find { type-> type.guid == value.first().ptguid }
                    DPProblemRecurrence().apply {
                        problemTag = key
                        problemType = type
                        count = value.size
                        changeCount = value.count { it.ischanged == true }
                        changePer = if (count == 0) 0.0 else changeCount.toDouble() / count
                    }
                }
            }
        )
    }
}