feiyu02
2024-09-25 0516cba27e632f20efac2752787f38f0c87baafa
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/score/AopEvaluation.kt
@@ -15,6 +15,7 @@
import cn.flightfeather.supervision.common.utils.UUIDGenerator
import cn.flightfeather.supervision.domain.ds1.entity.Evaluation
import cn.flightfeather.supervision.domain.ds1.entity.Itemevaluation
import cn.flightfeather.supervision.domain.ds1.entity.Subtask
import org.springframework.stereotype.Component
import java.util.*
import kotlin.math.abs
@@ -24,9 +25,9 @@
 */
@Component
class AopEvaluation(
    private val aopOutput: AopOutput,
    private val aopDbMapper: AopDbMapper,
    private val aopSceneTypeCheck: AopSceneTypeCheck,
    private val aopOutput: AopOutput,
    csScoreItem1: CsScoreItem1,
    csScoreItem2: CsScoreItem2,
    mpScoreItem1: MpScoreItem1,
@@ -35,15 +36,17 @@
    whScoreItem1: WhScoreItem1,
    whScoreItem2: WhScoreItem2,
    reScoreItem5: ReScoreItem5,
    reScoreItem7: ReScoreItem7,
    reScoreItem8: ReScoreItem8,
    reScoreItem9: ReScoreItem9,
    reScoreItem10: ReScoreItem10,
    reScoreItem11: ReScoreItem11,
) {
    //正在进行评估的巡查任务
    private val runningSubtask = mutableListOf<String>()
    //数据源
    private var source: AopDataSource? = null
    //正在进行评估的总巡查任务
    private val runningTopTask = mutableListOf<String>()
    //特定评分项(除了统一的根据巡查问题直接扣分外,有特定的扣分逻辑的评估项)
    private val itemList = mutableListOf<ScoreItem>()
@@ -57,7 +60,6 @@
            add(whScoreItem1)
            add(whScoreItem2)
            add(reScoreItem5)
            add(reScoreItem7)
            add(reScoreItem8)
            add(reScoreItem9)
            add(reScoreItem10)
@@ -65,26 +67,85 @@
        }
    }
    fun setResource(topTaskGuid: String?, sceneType: Int, districtName: String? = null, townCode: String? = null) {
        source = AopDataSource(aopDbMapper, aopSceneTypeCheck)
        source?.setResource(topTaskGuid, sceneType, districtName, townCode)
    fun executeByTopTask(topTaskGuid: String?, sceneType: Int, districtName: String? = null, townCode: String? = null) {
        val source = setResource(topTaskGuid, sceneType, districtName, townCode)
        execute(source)
    }
    /**
     * 对特定的巡查任务进行单独评分
     */
    fun executeBySubTask(subTask: Subtask) {
        if (checkSubtaskExist(subTask)) return
        val source = setResource(subTask)
        execute(source)
        runningSubtask.remove(subTask.stguid)
    }
    @Synchronized
    private fun checkTopTaskExist(topTaskGuid: String?): Boolean {
        return if (runningTopTask.contains(topTaskGuid)) {
            true
        } else {
            topTaskGuid?.let { runningTopTask.add(it) }
            false
        }
    }
    @Synchronized
    private fun checkSubtaskExist(subTask: Subtask): Boolean {
        return if (subTask.stguid == null || runningSubtask.contains(subTask.stguid)) {
            true
        } else {
            runningSubtask.add(subTask.stguid!!)
            false
        }
    }
    private fun setResource(subTask: Subtask): AopDataSource {
        val source = AopDataSource(aopDbMapper, aopSceneTypeCheck)
        source.setResource(subTask)
        return source
    }
    private fun setResource(
        topTaskGuid: String?,
        sceneType: Int,
        districtName: String?,
        townCode: String?,
    ): AopDataSource {
        val source = AopDataSource(aopDbMapper, aopSceneTypeCheck)
        source.setResource(topTaskGuid, sceneType, districtName, townCode)
        return source
    }
    /**
     * 执行评分逻辑
     */
    fun execute() {
        //获取数据源(待评估的场景)
        //循环处理每个场景
        source?.loop {index, evaluationScene ->
            if (evaluationScene.noRecord()) return@loop
    private fun execute(source: AopDataSource, isBySubtask: Boolean = false) {
        // 当需要只针对单词巡查任务进行评估时
        if (isBySubtask) {
            source.runBySubTask { index, evaluationScene ->
                if (evaluationScene.noRecord()) return@runBySubTask
            itemGrade(index, evaluationScene)
            totalGrade(index, evaluationScene)?.run {
                aopOutput.toDbEvaluation(evaluationScene, this)
                itemGrade(index, evaluationScene)
                totalGrade(index, evaluationScene)?.run {
                    aopOutput.toDbEvaluation(evaluationScene, this)
                }
            }
        }
        // 当针对场景进行评估时,要包括该场景当月可能存在的复核巡查情况
        else {
            //循环处理每个场景
            source.loop { index, evaluationScene ->
                if (evaluationScene.noRecord()) return@loop
                itemGrade(index, evaluationScene)
                totalGrade(index, evaluationScene)?.run {
                    aopOutput.toDbEvaluation(evaluationScene, this)
                }
            }
        }
    }
    /**
@@ -92,10 +153,10 @@
     */
    private fun itemGrade(index: Int, evaluationScene: AopDataSource.EvaluationScene) {
        // 规则条目得分初始化
        evaluationScene.topItems.value?.forEach { s -> s.extension1 = null }
        evaluationScene.topRules.value?.forEach { s -> s.clear() }
        evaluationScene.rules.value?.forEach { p ->
            p.first.extension1 = null
            p.second.forEach { e -> e.extension1 = null }
            p.first.clear()
            p.second.forEach { e -> e.clear() }
        }
        /** 1. 根据评分规则对应的问题自动判断是否扣分***************************************************************/
@@ -111,7 +172,7 @@
                // 存在多个评分项和同一个问题关联,因此必须全部评分项都判定一遍
                sr.problemlist?.split(",")?.forEach { pId ->
                    if (pList.contains(pId)) {
                        sr.extension1 = (0 - (sr.maxscore ?: 0)).toString()
                        sr.setMaxScore()
                    }
                }
            }
@@ -121,18 +182,21 @@
        /** 2.部分有特殊评分逻辑的规则进行计算*************************************************************************/
        itemList.forEach { item -> item.execute(evaluationScene) }
        /** 3. 补全各上级评分项的计分*************************************************************************/
        /** 3. 补充各上级评分项的计分*************************************************************************/
        evaluationScene.rules.value?.forEach { r ->
            val fatherId = r.first.fatherid
            for (t in (evaluationScene.topItems.value ?: emptyList())) {
            for (t in (evaluationScene.topRules.value ?: emptyList())) {
                if (t.guid == fatherId) {
                    var s = t.extension1?.toIntOrNull() ?: 0
                    s += r.first.extension1?.toIntOrNull() ?: 0
                    var s = t.score
                    s += r.first.score
                    // 限制最高扣分
                    if (abs(s) > (t.maxscore ?: 0)) {
                        s = 0 - (t.maxscore ?: 0)
                    }
                    t.extension1 = s.toString()
//                    if (abs(s) > (t.maxscore ?: 0)) {
////                        s = 0 - (t.maxscore ?: 0)
//                        t.setMaxScore()
//                    } else {
//                        t.score = s
//                    }
                    t.score = s
                    break
                }
            }
@@ -142,20 +206,23 @@
    /**
     * 计算总分
     */
    private fun totalGrade(index: Int, evaluationScene: AopDataSource.EvaluationScene): Pair<Evaluation, List<Itemevaluation>>? {
    private fun totalGrade(
        index: Int,
        evaluationScene: AopDataSource.EvaluationScene,
    ): Pair<Evaluation, List<Itemevaluation>>? {
        val scene = evaluationScene.scene.value ?: return null
        val topItems = evaluationScene.topItems.value ?: return null
        val topItems = evaluationScene.topRules.value ?: return null
        val rules = evaluationScene.rules.value ?: return null
        val subTask = evaluationScene.subTask.value
        val inspection = evaluationScene.inspection.value
        val totalScore = evaluationScene.totalScore.value ?: return null
        var total = 0//总扣除的分数
        evaluationScene.topItems.value?.forEach top@{ top ->
            total += top.extension1?.toIntOrNull() ?: 0
        evaluationScene.topRules.value?.forEach top@{ top ->
            total += top.score
        }
        val evaluation = Evaluation().apply {
                evaluationScene.baseRule.value?.let {
            evaluationScene.baseRule.value?.let {
                guid = UUIDGenerator.generate16ShortUUID()
                iguid = inspection?.guid
                stguid = subTask?.stguid