feiyu02
2024-09-25 0516cba27e632f20efac2752787f38f0c87baafa
src/main/kotlin/cn/flightfeather/supervision/business/autooutput/score/ScoreUtil.kt
@@ -1,52 +1,170 @@
package cn.flightfeather.supervision.business.autooutput.score
import cn.flightfeather.supervision.business.Info
import cn.flightfeather.supervision.business.autooutput.datasource.AopDataSource
import cn.flightfeather.supervision.common.utils.ExcelUtil
import cn.flightfeather.supervision.common.utils.UUIDGenerator
import cn.flightfeather.supervision.domain.ds1.entity.Evaluationrule
import cn.flightfeather.supervision.domain.ds1.entity.Evaluationsubrule2
import cn.flightfeather.supervision.domain.ds1.entity.Inspection
import cn.flightfeather.supervision.domain.ds1.entity.Evaluation
import cn.flightfeather.supervision.lightshare.vo.EvaluationSubRuleVo
import cn.flightfeather.supervision.domain.ds1.entity.Itemevaluation
import org.apache.poi.hssf.util.HSSFColor
import kotlin.math.abs
import cn.flightfeather.supervision.lightshare.vo.EvaluationVo
import cn.flightfeather.supervision.lightshare.vo.ItemEvaluationVo
import java.util.*
/**
 * 得分计算工具
 * 评分表格分为三个层级
 * 第一层为大分类,第二层为评估标准,第三层为标准对应的不同程度的评估结果
 */
// FIXME: 2024/9/23 目前暂按照三层评估规则进行评估,后续应该优化为不限层数
object ScoreUtil {
    /**
     * 计算某一具体评分标准的得分
     * 针对减分模式
     * 根据所选最深层评估选项,给规则赋值对应分数及自动计算其余所有条目得分
     * @param evaluationScene 需要评估的对象
     * @param selected 评估表中选中的评估条目主键id集合(必须是最深一层的评估条目)
     */
    fun subRuleCal(rulePair: Pair<Evaluationsubrule2, MutableList<Evaluationsubrule2>>?) {
    fun scoreAssign(evaluationScene: AopDataSource.EvaluationScene, selected: List<String>) {
        val topRules = evaluationScene.topRules.value
        val subRules = evaluationScene.rules.value
        subRules?.forEach { r ->
            // 根据传入的选中评估条目主键id,修改其得分
            r.second.forEach { e ->
                if (selected.contains(e.guid)) {
                    e.setMaxScore()
                }
            }
            // 根据子项的选择情况,自动计算该条评估的总得分
            subRuleCal(r)
            // 补充各最上级评分项的计分
            val fatherId = r.first.fatherid
            for (t in (evaluationScene.topRules.value ?: emptyList())) {
                if (t.guid == fatherId) {
                    t.score += r.first.score
                    break
                }
            }
        }
    }
    /**
     * 计算某一具体评分标准的得分,并且根据选项和分数上限计算最终得分
     * @param rulePair 二级和三级评分规则的对应结构
     */
    fun subRuleCal(rulePair: Pair<EvaluationSubRuleVo, MutableList<EvaluationSubRuleVo>>?) {
        val rule = rulePair?.first
        val itemList = rulePair?.second
        var total: Int? = null
        var total = 0
        itemList?.forEach {
            if (!it.extension1.isNullOrBlank()) {
                total = (total ?: 0) + it.extension1!!.toInt()
            total += it.score
        }
//        val s = if (abs(total) > rule?.maxscore!!) {
//            when (rule.extension2) {
//                // 减分模式,记录为扣分(负数)
//                Constant.EvaGradeMode.MINUS_MODE.value -> {
//                    0 - rule.maxscore!!
//                }
//                // 加分模式,记录为得分(正数)
//                Constant.EvaGradeMode.ADD_MODE.value -> {
//                    rule.maxscore!!
//                }
//                // 默认减分模式
//                else -> {
//                    0 - rule.maxscore!!
//                }
//            }
//        } else {
//            total
//        }
//        rule.score = s
        rule?.score = total
    }
    /**
     * 生成评估记录结果
     * @param evaluationScene 需要评估的对象
     * @return 评估总分和对应细则得分的数据库结构
     */
    fun genEvaRecord(evaluationScene: AopDataSource.EvaluationScene): Pair<Evaluation, List<Itemevaluation>>? {
        val scene = evaluationScene.scene.value ?: return null
        val topRules = evaluationScene.topRules.value ?: return null
        val baseRule = evaluationScene.baseRule.value
        val rules = evaluationScene.rules.value ?: return null
        val subTask = evaluationScene.subTask.value
        val inspection = evaluationScene.inspection.value
        var total = 0 //总得分
        topRules.forEach top@{ top ->
            total += top.getFinalScore()
        }
        val evaluation = EvaluationVo.newAutoEvaluation(inspection, subTask, scene, baseRule, total)
        //子项具体得分
        val itemList = mutableListOf<Itemevaluation>()
        topRules.forEach { subRule ->
            val item = ItemEvaluationVo.newItemEvaluation(baseRule, subTask, inspection, subRule)
            itemList.add(item)
        }
        rules.forEach { p ->
            if (p.first.ertype != 2) {
                val item = ItemEvaluationVo.newItemEvaluation(baseRule, subTask, inspection, p.first)
                itemList.add(item)
            }
            p.second.forEach { r ->
                val item1 = ItemEvaluationVo.newItemEvaluation(baseRule, subTask, inspection, r)
                itemList.add(item1)
            }
        }
        if (total == null) {
            rule?.extension1 = "0"
        } else {
            val s = if (abs(total!!) > rule?.maxscore!!) {
                0 - rule.maxscore!!
            } else {
                total
            }
            rule.extension1 = s.toString()
        return Pair(evaluation, itemList)
    }
    /**
     * 更新评估记录结果
     * @param evaluationScene 需要评估的对象
     * @return 评估总分和对应细则得分的数据库结构
     */
    fun updateEvaRecord(evaluationScene: AopDataSource.EvaluationScene): Pair<Evaluation, List<Itemevaluation>>? {
        val topRules = evaluationScene.topRules.value ?: return null
        val rules = evaluationScene.rules.value ?: return null
        val evaluation = evaluationScene.evaluation.value ?: return null
        val itemevaluationList = evaluationScene.itemevaluationList.value ?: return null
        var total = 0 //总得分
        topRules.forEach top@{ top ->
            total += top.getFinalScore()
        }
        evaluation.apply {
            resultscorebef = total.toString()
            updatedate = Date()
        }
        //子项具体得分
        topRules.forEach { subRule ->
            itemevaluationList.find { it.esrguid == subRule.guid }?.let {
                it.value = subRule.score.toString()
                it.extension1 = subRule.selected.toString()
            }
        }
        rules.forEach { p ->
            // 可能存在第一层级下属直接为第三层级的情况
            if (p.first.ertype != 2) {
                itemevaluationList.find { it.esrguid == p.first.guid }?.let {
                    it.value = p.first.score.toString()
                    it.extension1 = p.first.selected.toString()
                }
            }
            p.second.forEach { r ->
                itemevaluationList.find { it.esrguid == r.guid }?.let {
                    it.value = r.score.toString()
                    it.extension1 = r.selected.toString()
                }
            }
        }
        return Pair(evaluation, itemevaluationList)
    }
    /**
     * 生成新的一条评分记录
     */
    fun newItemEvaluation(evaluationScene: AopDataSource.EvaluationScene, itemRule: Evaluationsubrule2) =
    fun newItemEvaluation(evaluationScene: AopDataSource.EvaluationScene, itemRule: EvaluationSubRuleVo) =
        Itemevaluation().apply {
            val rule = evaluationScene.baseRule.value
            val subTask = evaluationScene.subTask.value
@@ -62,8 +180,8 @@
            ertype = itemRule.ertype
            esrguid = itemRule.guid
            name = itemRule.itemname
            value = itemRule.extension1 ?: "0"
            extension1 = (itemRule.extension1 != null).toString()
            value = itemRule.score.toString()
            extension1 = itemRule.selected.toString()
        }
    /**