package cn.flightfeather.supervision.business
|
|
import cn.flightfeather.supervision.domain.ds1.entity.*
|
import cn.flightfeather.supervision.common.utils.UUIDGenerator
|
import cn.flightfeather.supervision.lightshare.service.*
|
import cn.flightfeather.supervision.lightshare.vo.InspectionVo
|
import cn.flightfeather.supervision.lightshare.vo.ProblemlistVo
|
import cn.flightfeather.supervision.lightshare.vo.ScenseVo
|
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.stereotype.Component
|
import java.math.RoundingMode
|
import java.util.*
|
import javax.annotation.PostConstruct
|
import kotlin.collections.ArrayList
|
|
/**
|
* @author riku
|
* 2019.3.15
|
* 自动评分
|
* 根据取证问题自动得出默认评分
|
* 评分项分为2、3、4三种分类等级,2为最大的分类、4为最小(最详细)的分类,
|
* 通过对等级为4的评分项进行具体打分,分别根据附属关系统计得出等级3、2的总得分,
|
* 最终所有等级2的评分项求和即为总分
|
*/
|
|
@Component
|
class AutoScore {
|
|
companion object {
|
private lateinit var autoScore: AutoScore
|
|
//问题关键词,包含此关键词的问题区别对待
|
private final var TOPIC = "积尘"
|
}
|
|
@Autowired
|
lateinit var problemlistService: ProblemlistService
|
@Autowired
|
lateinit var evaluationruleService: EvaluationruleService
|
@Autowired
|
lateinit var evaluationsubruleService: EvaluationsubruleService
|
@Autowired
|
lateinit var scenseService: ScenseService
|
@Autowired
|
lateinit var inspectionService: InspectionService
|
@Autowired
|
lateinit var evaluationService: EvaluationService
|
@Autowired
|
lateinit var itemevaluationService: ItemevaluationService
|
|
private var problems: ArrayList<ProblemlistVo> = ArrayList()
|
|
private var allRules: ArrayList<Evaluationsubrule> = ArrayList()
|
|
private var inspection = InspectionVo()
|
|
private var evaluationrule: Evaluationrule? = null
|
|
private var scense: ScenseVo? = null
|
|
private var totalPoint = 0
|
|
//子评分项得分列表
|
val childScorelist = ArrayList<Itemevaluation>()
|
//总分
|
val totalScore = Evaluation()
|
|
var subtask = Subtask()
|
|
var rate = 1f
|
|
val random = Random()
|
|
// var getTotalPointDone = false
|
|
@PostConstruct
|
fun init() {
|
autoScore = this
|
autoScore.problemlistService = this.problemlistService
|
autoScore.evaluationruleService = this.evaluationruleService
|
autoScore.evaluationsubruleService = this.evaluationsubruleService
|
autoScore.scenseService = this.scenseService
|
autoScore.inspectionService = this.inspectionService
|
autoScore.evaluationService = this.evaluationService
|
autoScore.itemevaluationService = this.itemevaluationService
|
}
|
|
fun test(): InspectionVo {
|
return autoScore.inspectionService.findByID("048ENlnke0L8C9Gi")
|
}
|
|
fun calculateScore() {
|
//获取子任务对应的问题列表
|
this.problems.addAll(autoScore.problemlistService.findBySubtaskId(subtask.stguid!!))
|
//获取子任务对应的场景信息
|
scense = autoScore.scenseService.findOne(subtask.scenseid!!)
|
//获取对应任务类型、场景类型、区县的评分表名称
|
val evaluationrule = autoScore.evaluationruleService.findBySpecificRule(subtask.typeno, scense!!.typeid, subtask.districtcode)
|
if (evaluationrule === null) return
|
this.evaluationrule = evaluationrule
|
//获取对应的具体评分细则
|
allRules = autoScore.evaluationsubruleService.findByRuleId(evaluationrule.guid!!) as ArrayList<Evaluationsubrule>
|
//获取巡查信息
|
inspection = autoScore.inspectionService.findBySubTaskID(subtask.stguid!!)
|
|
|
//目标分数
|
val goalScore = getGoalScore(this.problems)
|
|
val titleRule = Evaluationsubrule()
|
val titleOptionRange = ArrayList<Int>()
|
val titleIsGood = true
|
|
totalPoint = getTotalPoint(allRules, titleRule.guid)
|
rate = goalScore.toFloat() / totalPoint.toFloat()
|
|
//得到的point是扣分分数
|
var point = autoGeneration(titleRule, titleOptionRange, titleIsGood)
|
point?.let { adJustTotalPoint(totalPoint -Math.abs(it), goalScore) }
|
point = getTotalPointAfterAdJust()
|
createTotalScore(point)
|
update()
|
}
|
|
/**
|
* 获取最终总得分
|
*/
|
fun getTotalPointAfterAdJust(): Int? {
|
val subRules = getSubRulesByFatherId(allRules, null)
|
var point = 0
|
subRules.forEach {
|
for (c in childScorelist) {
|
if (!c.value.isNullOrBlank()
|
&& it.guid == c.esrguid) {
|
point += c.value?.toInt() ?: 0
|
}
|
}
|
}
|
|
return point
|
}
|
|
/**
|
* 自动打分
|
* @param fatherRule
|
* @param optionRange
|
* @param isGood
|
*/
|
fun autoGeneration(fatherRule: Evaluationsubrule, optionRange: ArrayList<Int>?, isGood: Boolean): Int? {
|
|
val nextSubRules = getSubRulesByFatherId(allRules, fatherRule.guid)
|
//无子项的最小评分项,给出得分
|
if (nextSubRules.isEmpty()) {
|
val totalScore = writeScore4th(fatherRule, optionRange, isGood, rate)
|
createNewChildScore(fatherRule, totalScore)
|
return totalScore
|
}
|
//有子项的评分项,以每项子项为父项继续递归,获取总分
|
else {
|
var totalScore = 0//有子项的评分项一定会有分数,不会出现null的情况
|
var nextIsGood = isGood
|
var nextOptionRange = getOptionRange(fatherRule.guid, isGood, fatherRule.extension1)
|
if (isGood) {
|
for (problem in problems) {
|
if (!fatherRule.problemlist.isNullOrBlank()) {
|
if (fatherRule.problemlist!!.contains(problem.ptguid ?: "null")) {
|
nextOptionRange = getOptionRange(fatherRule.guid!!, !isGood, fatherRule.extension1)
|
nextIsGood = false
|
break
|
}
|
}
|
}
|
}
|
|
var nextTmpTotalScore = 0//所有子项的总得分
|
nextSubRules.forEach {
|
val nextFatherRule = it
|
val score = autoGeneration(nextFatherRule, nextOptionRange, nextIsGood)
|
if (score != null) {
|
nextTmpTotalScore += score
|
}
|
}
|
|
if (nextTmpTotalScore >= (0-(fatherRule.maxscore?: totalPoint))) {
|
totalScore += nextTmpTotalScore
|
} else {
|
reGrade(nextSubRules, nextOptionRange, fatherRule.maxscore!!)
|
}
|
//取得总分后,生成对应的评分信息并存入列表
|
if (!fatherRule.guid.isNullOrBlank())
|
createNewChildScore(fatherRule, totalScore)
|
|
return totalScore
|
}
|
}
|
|
//填写详细评分项的分数
|
fun writeScore4th(rule: Evaluationsubrule, optionRange: ArrayList<Int>?, isGood: Boolean, rate: Float): Int? {
|
|
val optionId = (rule.displayid?.toInt() ?: 1) - 1
|
if (optionRange?.contains(optionId) == true) {
|
//取得可选分数的中间值
|
val maxScore = rule.maxscore
|
val minScore = rule.minscore
|
val middleScore = (maxScore!! + minScore!!) / 2
|
|
var tmpScore = 0
|
|
val b = (maxScore * rate).toBigDecimal()
|
|
if (isGood) {
|
tmpScore = b.setScale(0, RoundingMode.HALF_UP).toInt()
|
// if ((maxScore-tmpScore)!=0) {
|
// tmpScore += random.nextInt(maxScore - tmpScore)
|
// }
|
//目前评分为减分规则,只记录减分
|
tmpScore = 0 - (maxScore - tmpScore)
|
} else {
|
//较差选项的评分在“最小分~中间分”中随机选取(包含中间值)
|
tmpScore = if ((maxScore + minScore) % 2 == 0) {
|
random.nextInt(maxScore - middleScore + 1) + minScore
|
} else {
|
random.nextInt(maxScore - middleScore) + minScore
|
}
|
//目前评分为减分规则,只记录减分
|
tmpScore = 0 - (maxScore - tmpScore)
|
}
|
|
return tmpScore
|
}
|
//若不需要评分,此处将其设置为空
|
return null
|
}
|
|
//按照父id查找子评分项
|
fun getSubRulesByFatherId(rules: ArrayList<Evaluationsubrule>, fatherId: String?): List<Evaluationsubrule> {
|
val subRules = mutableListOf<Evaluationsubrule>()
|
rules.forEach {
|
if (it.fatherid == fatherId
|
|| (fatherId.isNullOrBlank() && it.fatherid.isNullOrBlank())) {
|
subRules.add(it)
|
// rules.remove(it)
|
}
|
}
|
return subRules
|
}
|
|
//获取随机评分的评分项列表
|
fun getOptionRange(fatherId: String?, isGood: Boolean, mutiChoice: String?): ArrayList<Int>? {
|
if (fatherId.isNullOrBlank()) return ArrayList<Int>()
|
val nextSubRules = getSubRulesByFatherId(allRules, fatherId)
|
val list = ArrayList<Int>()
|
val size = nextSubRules.size
|
val midIndex = Math.ceil((size.toDouble() / 2.toDouble())).toInt()
|
|
when (mutiChoice) {
|
//单选
|
"0" -> {
|
val index = if (isGood) {
|
random.nextInt(midIndex)
|
} else {
|
random.nextInt(midIndex) + midIndex
|
}
|
list.add(index)
|
}
|
//多选
|
"1" -> {
|
val optionNum = random.nextInt(size) + 1//选项个数
|
for (i in 1..optionNum) {
|
var index = random.nextInt(size)
|
while (list.contains(index)) {
|
index = random.nextInt(size)
|
}
|
list.add(index)
|
}
|
}
|
//全选
|
"2" -> {
|
for (index in nextSubRules.indices) {
|
list.add(index)
|
}
|
}
|
null -> return null
|
}
|
|
return list
|
}
|
|
//多选项评分超过总分,重新分配分数
|
fun reGrade(subRules: List<Evaluationsubrule>, optionRange: ArrayList<Int>?, maxScore: Int) {
|
var remainScore = maxScore
|
val a = optionRange?.size ?: 1
|
|
for (it in subRules) {
|
if (optionRange?.contains(it.displayid?.toInt()) == true) {
|
var score = random.nextInt(maxScore / a)
|
remainScore -= score
|
if (remainScore < 0) {
|
score = remainScore
|
}
|
//<editor-fold desc="更新分数(减分模式)">
|
for (c in childScorelist) {
|
if (c.esrguid == it.guid) {
|
c.value = (0 - score).toString()
|
break
|
}
|
}
|
//</editor-fold>
|
|
//<editor-fold desc="总分被扣完后,不再评分">
|
if (remainScore <= 0) {
|
break
|
}
|
//</editor-fold>
|
}
|
}
|
}
|
|
//创建单项评分对象
|
fun createNewChildScore(subRule: Evaluationsubrule, score: Int?) {
|
val itemevaluation = Itemevaluation()
|
itemevaluation.ieguid = UUIDGenerator.generate16ShortUUID()
|
itemevaluation.iguid = inspection.guid
|
itemevaluation.stguid = subtask.stguid
|
itemevaluation.sguid = subtask.scenseid
|
itemevaluation.sensename = subtask.scensename
|
itemevaluation.erguid = evaluationrule!!.guid
|
itemevaluation.rulename = evaluationrule!!.rulename
|
itemevaluation.ruletype = 2
|
// itemevaluation.ertype = subRule.ertype
|
itemevaluation.esrguid = subRule.guid
|
itemevaluation.name = subRule.itemname
|
if (score === null) {
|
itemevaluation.value = null
|
} else {
|
itemevaluation.value = score.toString()
|
}
|
childScorelist.add(itemevaluation)
|
}
|
|
//创建总分对象
|
fun createTotalScore(point: Int?) {
|
totalScore.guid = UUIDGenerator.generate16ShortUUID()
|
totalScore.iguid = inspection.guid
|
totalScore.stguid = subtask.stguid
|
totalScore.sguid = scense?.guid
|
totalScore.scensetypeid = scense?.typeid
|
totalScore.scensetype =scense?.type
|
totalScore.subscensetypeid = scense?.scensesubtypeid
|
totalScore.subscensetype = scense?.scensesubtype
|
totalScore.ertype = evaluationrule?.ruletype?.toByte()
|
totalScore.provincecode = scense?.provincecode
|
totalScore.provincename = scense?.provincename
|
totalScore.citycode = scense?.citycode
|
totalScore.cityname = scense?.cityname
|
totalScore.districtcode = scense?.districtcode
|
totalScore.districtname = scense?.districtname
|
totalScore.towncode = scense?.towncode
|
totalScore.townname = scense?.townname
|
totalScore.scensename = scense?.name
|
totalScore.scenseaddress = scense?.location
|
totalScore.evaluatetime = Date()
|
totalScore.evaluatorguid = "admin"
|
totalScore.evaluatorusername = "admin"
|
totalScore.evaluatorrealname = "admin"
|
totalScore.createdate = Date()
|
totalScore.resultscorebef = (totalPoint - Math.abs(point!!)).toInt().toString()
|
}
|
|
//获取总分
|
fun getTotalPoint(rules: ArrayList<Evaluationsubrule>, fatherId: String?): Int {
|
val rules1 = getSubRulesByFatherId(rules, fatherId)
|
var point = 0
|
rules1.forEach {
|
point += it.maxscore?: 0
|
}
|
return point
|
}
|
|
//数据库更新
|
fun update() {
|
// println(totalScore)
|
autoScore.evaluationService.save(totalScore)
|
childScorelist.forEach {
|
autoScore.itemevaluationService.save(it)
|
// println(it)
|
}
|
}
|
|
//根据问题个数随机获取应得总分
|
fun getGoalScore(problems: ArrayList<ProblemlistVo>): Int {
|
var result = 0
|
var p = 0
|
var c = 2
|
problems.forEach {
|
p += if (it.problemname?.contains(TOPIC) == true) {
|
5
|
} else {
|
10
|
}
|
if (it.ischanged == false) {
|
c = if (!it.changecatalog.isNullOrBlank()) {
|
1
|
} else {
|
0
|
}
|
}
|
}
|
result = when (p) {
|
0 -> {
|
randomScore(3, 20, 5)
|
}
|
in 1..5 -> {
|
randomScore(c, 42, 7)
|
}
|
10 ->{
|
randomScore(c, 50, 7)
|
}
|
in 15..40 -> {
|
randomScore(c, 66, 21)
|
}
|
else -> {
|
randomScore(c, 75, 8)
|
}
|
|
}
|
return result
|
}
|
|
private fun randomScore(c: Int, p: Int, t:Int): Int {
|
println(p / 3)
|
return random.nextInt(t / 3) + 120 - p + t * c / 3
|
}
|
|
//调整最终分数
|
fun adJustTotalPoint(totalPoint: Int, goalScore: Int) {
|
var value = goalScore - totalPoint
|
var fatherRule = Evaluationsubrule()
|
var subRules = ArrayList<Evaluationsubrule>()
|
|
for (it in allRules) {
|
if (it.itemname == "附加分") {
|
fatherRule = it
|
subRules = getSubRulesByFatherId(allRules, fatherRule.guid) as ArrayList<Evaluationsubrule>
|
break
|
}
|
}
|
value = foo1(fatherRule, subRules, value)
|
|
}
|
|
private fun foo1(fatherRule: Evaluationsubrule, subRules: List<Evaluationsubrule>, remainValue: Int): Int {
|
var value = remainValue
|
for (it in childScorelist) {
|
if (it.name == fatherRule.itemname) {
|
val culValue = it.value?.toInt()
|
var tmp = culValue
|
tmp = tmp?.plus(value)
|
if (tmp != null) when {
|
tmp > 0 -> {
|
value -= (fatherRule.minscore ?: 0) - culValue!!
|
it.value = fatherRule.minscore.toString()
|
}
|
tmp < 0 - (fatherRule.maxscore ?: 20) -> {
|
value -= (0 - (fatherRule.maxscore ?: 20)) - culValue!!
|
it.value = (0 - (fatherRule.maxscore ?: 20)).toString()
|
}
|
else -> it.value = tmp.toString()
|
}
|
for (s in subRules) {
|
loop@ for (i in childScorelist) {
|
if (s.guid == i.esrguid
|
&& i.value != null) {
|
i.value = it.value
|
break@loop
|
}
|
}
|
}
|
break
|
}
|
}
|
return value
|
}
|
}
|