feiyu02
2025-08-14 f373bbf83d9d2a7e5f96118d7dcd658c9fea8bc8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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())
    }
}