package cn.flightfeather.supervision.common.score
|
|
import cn.flightfeather.supervision.common.score.item.*
|
import cn.flightfeather.supervision.common.score.Info
|
import cn.flightfeather.supervision.domain.entity.*
|
import cn.flightfeather.supervision.domain.enumeration.SceneType
|
import cn.flightfeather.supervision.domain.enumeration.UserType
|
import cn.flightfeather.supervision.domain.mapper.*
|
import cn.flightfeather.supervision.infrastructure.utils.DateUtil
|
import cn.flightfeather.supervision.infrastructure.utils.ExcelUtil
|
import cn.flightfeather.supervision.infrastructure.utils.UUIDGenerator
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook
|
import org.apache.poi.hssf.util.HSSFColor
|
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.stereotype.Component
|
import tk.mybatis.mapper.entity.Example
|
import java.io.File
|
import java.io.FileOutputStream
|
import java.time.*
|
import java.util.*
|
import javax.annotation.PostConstruct
|
import kotlin.math.abs
|
|
/**
|
* 自动评分
|
*/
|
@Component
|
class AutoScore(
|
val scoreItem_1: ScoreItem_1, val scoreItem_2: ScoreItem_2, val scoreItem_3: ScoreItem_3,
|
val scoreItem_4: ScoreItem_4, val scoreItem_5: ScoreItem_5, val scoreItem_6: ScoreItem_6,
|
val scoreItem_7: ScoreItem_7, val scoreItem_8: ScoreItem_8, val scoreItem_9: ScoreItem_9,
|
val scoreItem_10: ScoreItem_10, val scoreItem_11: ScoreItem_11, val scoreItem_12: ScoreItem_12, val scoreItem_13: ScoreItem_13
|
) {
|
companion object {
|
private lateinit var instance: AutoScore
|
//特殊评分项,计算总分时,若此评分项得分,当加上此评分项后的总分不超过得分上限,则计算,否则舍去
|
private const val SPECIAL_RULE = "监测设备"
|
|
// private val SCENE_TYPE = SceneType.Restaurant
|
private val SCENE_TYPE = SceneType.VehicleRepair
|
}
|
|
@PostConstruct
|
fun init() {
|
instance = this
|
}
|
|
@Autowired
|
lateinit var userinfoMapper: UserinfoMapper
|
|
@Autowired
|
lateinit var evaluationruleMapper: EvaluationruleMapper
|
|
@Autowired
|
lateinit var evaluationsubruleMapper: EvaluationsubruleMapper
|
|
@Autowired
|
lateinit var evaluationMapper: EvaluationMapper
|
|
@Autowired
|
lateinit var itemevaluationMapper: ItemevaluationMapper
|
|
@Autowired
|
lateinit var overallEvaluationMapper: OverallEvaluationMapper
|
|
private var totalScore = 100//满分
|
|
private val itemList = mutableListOf<ScoreItem>()
|
|
private val baseRules = mutableListOf<Evaluationrule>()
|
|
private val rules = mutableListOf<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>()
|
|
private val topItems = mutableListOf<Evaluationsubrule>()
|
|
private var workbook = HSSFWorkbook()
|
|
init {
|
itemList.apply {
|
add(scoreItem_1)
|
add(scoreItem_2)
|
add(scoreItem_3)
|
add(scoreItem_4)
|
add(scoreItem_5)
|
add(scoreItem_6)
|
add(scoreItem_7)
|
add(scoreItem_8)
|
add(scoreItem_9)
|
add(scoreItem_10)
|
add(scoreItem_11)
|
add(scoreItem_12)
|
add(scoreItem_13)
|
}
|
}
|
|
fun go(_year: Int? = null, _month: Int? = null) {
|
val fileName = "汽修自动评分-${DateUtil().DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
|
val filePath = "E:\\工作\\开发\\飞羽环境app\\自动评分\\汽修\\$fileName"
|
val out = FileOutputStream(File(filePath))
|
|
getScoreItem()
|
|
val userList = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
|
createCriteria().andEqualTo("usertypeid", UserType.Enterprise.value.toByte())
|
// FIXME: 2021/4/28 场景类型
|
// 汽修类型
|
.andEqualTo("extension2", SCENE_TYPE.value.toString())
|
// 餐饮类型
|
// .andEqualTo("extension2", SCENE_TYPE.value.toString())
|
// orderBy("workno")
|
})
|
|
val contents = mutableListOf<Array<Any>>()
|
|
val h1 = mutableListOf<ExcelUtil.MyCell>()
|
h1.add(ExcelUtil.MyCell(""))
|
val h2 = mutableListOf<ExcelUtil.MyCell>()
|
h2.add(ExcelUtil.MyCell(""))
|
val h3 = mutableListOf<String>()
|
h3.add("")
|
topItems.forEach {
|
h1.add(ExcelUtil.MyCell(it.itemname ?: "", 1, 0))
|
for (r in rules) {
|
if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
|
h2.add(ExcelUtil.MyCell(r.first.itemname ?: "", 1, 0))
|
// FIXME: 2021/4/25 决定是否写h3
|
// r.second.forEach { s ->
|
// h3.add(s.itemname ?: "")
|
// h2.last().colSpan++
|
// h1.last().colSpan++
|
// }
|
h2.last().colSpan++
|
h1.last().colSpan++
|
}
|
}
|
}
|
// FIXME: 2021/4/25 决定是否写h3
|
// h1.add(ExcelUtil.MyCell("总分", 3, 1))
|
// h1.add(ExcelUtil.MyCell("环信码", 3, 1))
|
h1.add(ExcelUtil.MyCell("总分", 2, 1))
|
h1.add(ExcelUtil.MyCell("环信码", 2, 1))
|
|
|
contents.add(h1.toTypedArray())
|
contents.add(h2.toTypedArray())
|
// FIXME: 2021/4/25 决定是否写h3
|
// contents.add(h3.toTypedArray())
|
|
val now = LocalDate.now()
|
val year = _year ?: now.year
|
val month = _month ?: now.monthValue
|
val sMonth = DateUtil().getStartMonthByPeriod(month, 3) ?: 1
|
val eMonth = sMonth + 2
|
val period = "${year}/$sMonth-$eMonth"
|
|
userList.forEach {
|
topItems.forEach { s -> s.extension1 = null }
|
rules.forEach { p ->
|
p.first.extension1 = null
|
p.second.forEach { e -> e.extension1 = null }
|
}
|
|
val info = Info(
|
it.guid,
|
it.acountname,
|
it.realname,
|
SCENE_TYPE,
|
year,
|
month
|
)
|
|
var score = 0
|
|
//具体评分子项
|
val itemEvaluations = mutableListOf<Itemevaluation>()
|
for (i in itemList.indices) {
|
val result = itemList[i].execute(info)
|
val rule = this.rules[i]
|
var totalScore = 0
|
var checked = false
|
for (y in rule.second.indices) {
|
val itemRule = rule.second[y]
|
if (result.first == y) {
|
val s = result.second?.minus(rule.first.maxscore ?: 0) ?: 0
|
itemRule.extension1 = s.toString()
|
totalScore += s
|
checked = true
|
}
|
}
|
rule.first.apply {
|
if (checked) {
|
extension1 = totalScore.toString()
|
}
|
}
|
}
|
|
//评分大项
|
this.rules.forEach { r ->
|
val fatherId = r.first.fatherid
|
for (t in topItems) {
|
if (t.guid == fatherId) {
|
var s = t.extension1?.toIntOrNull() ?: 0
|
s += r.first.extension1?.toIntOrNull() ?: 0
|
t.extension1 = s.toString()
|
break
|
}
|
}
|
}
|
|
//总分
|
var total = 0//总扣除的分数
|
topItems.forEach top@{ top ->
|
// fixme 此处有一条特殊条目 SPECIAL_RULE 当前分数不超过95分时,如果此条目得分,则额外加在总分上
|
if (top.itemname == SPECIAL_RULE && abs(totalScore) <= (top.maxscore ?: 0)) {
|
return@top
|
}
|
total += top.extension1?.toIntOrNull() ?: 0
|
}
|
val evaluationList = mutableListOf<Evaluation>()
|
var evaluationId: String? = null
|
baseRules.forEach {
|
val evaluation = cn.flightfeather.supervision.domain.entity.Evaluation().apply {
|
guid = UUIDGenerator.generate16ShortUUID()
|
iguid = info.userId
|
stguid = it.guid
|
scensetypeid = info.sceneType.value.toByte()
|
ertype = it.ruletype?.toByte()
|
scensename = period
|
evaluatorguid = "system"
|
evaluatorusername = "system"
|
evaluatorrealname = "2"
|
resultscorebef = (totalScore - abs(total)).toString()
|
createdate = Date()
|
updatedate = Date()
|
}
|
if (evaluation.ertype?.toInt() == 1) {
|
evaluationId = evaluation.guid
|
}
|
evaluationList.add(evaluation)
|
}
|
//子项具体得分
|
val itemevaluationList = mutableListOf<Itemevaluation>()
|
topItems.forEach { subRule ->
|
val item = newItemEvaluation(info, subRule, evaluationId)
|
itemevaluationList.add(item)
|
}
|
rules.forEach { p ->
|
if (p.first.ertype != 2) {
|
val item = newItemEvaluation(info, p.first, evaluationId)
|
itemevaluationList.add(item)
|
}
|
p.second.forEach { r ->
|
val item1 = newItemEvaluation(info, r, evaluationId)
|
itemevaluationList.add(item1)
|
}
|
}
|
// 添加至文档
|
addToFile(contents, info, evaluationList, topItems, this.rules)
|
// write2File(info, evaluationList, topItems, this.rules)
|
val r = evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
|
createCriteria().andEqualTo("scensename", period)
|
.andEqualTo("evaluatorguid", "system")
|
.andEqualTo("iguid", info.userId)
|
// .andEqualTo("ertype", 1)
|
}).let { eList ->
|
var guid: String? = null
|
for (e in eList) {
|
if (e.ertype?.toInt() == 1) {
|
guid = e.guid
|
break
|
}
|
}
|
guid?.let {
|
eList.forEach { e ->
|
evaluationMapper.delete(e)
|
}
|
itemevaluationMapper.deleteByExample(Example(Itemevaluation::class.java).apply {
|
createCriteria().andEqualTo("sguid", guid)
|
})
|
}
|
} ?: 0
|
// 写入数据库
|
// for (e in evaluationList) {
|
// if (e.ertype?.toInt()?.equals(0) == true) {
|
// finalScore(e, year, eMonth, period)
|
// break
|
// }
|
// }
|
}
|
|
// 写入文档
|
ExcelUtil.write2(emptyList(), contents, workbook)
|
workbook.write(out)
|
workbook.close()
|
out.flush()
|
out.close()
|
}
|
|
/**
|
* 获取评分规则
|
*/
|
private fun getScoreItem() {
|
this.rules.clear()
|
baseRules.clear()
|
|
val rule = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
|
createCriteria()
|
.andEqualTo("tasktypeid", 1)
|
.andEqualTo("scensetypeid", SceneType.VehicleRepair.value.toByte())
|
.andEqualTo("districtcode", "310104")
|
})
|
if (rule.isNotEmpty()) {
|
baseRules.addAll(rule)
|
|
val ruleId = rule[0].guid
|
val rules = evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule::class.java).apply {
|
createCriteria().andEqualTo("erguid", ruleId)
|
})
|
rules.forEach {
|
if (it.ertype == 2) {
|
topItems.add(it)
|
}
|
}
|
topItems.sortBy { it.displayid }
|
|
var t = 0
|
topItems.forEach {
|
t += it.maxscore ?: 0
|
val tempRules = mutableListOf<Evaluationsubrule>()
|
for (i in rules) {
|
if (i.fatherid == it.guid && i.ertype == 3) {
|
tempRules.add(i)
|
}
|
}
|
//评分大项如果没有找到评分小项,则说明其直接对应最小评分项,其本身变成评分项
|
if (tempRules.isEmpty()) {
|
tempRules.add(it)
|
}
|
tempRules.sortBy { t-> t.displayid }
|
tempRules.forEach {temp ->
|
val tempSubRules = mutableListOf<Evaluationsubrule>()
|
for (i in rules) {
|
if (i.fatherid == temp.guid && i.ertype == 4) {
|
tempSubRules.add(i)
|
}
|
}
|
tempSubRules.sortBy {ts-> ts.displayid }
|
this.rules.add(Pair(temp, tempSubRules))
|
}
|
}
|
// this.totalScore = t
|
}
|
}
|
|
/**
|
* 生成新的一条评分记录
|
*/
|
private fun newItemEvaluation(info: Info, itemRule: Evaluationsubrule, evaluationId: String?) = cn.flightfeather.supervision.domain.entity.Itemevaluation()
|
.apply {
|
var rule: Evaluationrule? = null
|
for (r in baseRules) {
|
if (r.guid == itemRule.erguid) {
|
rule = r
|
break
|
}
|
}
|
ieguid = UUIDGenerator.generate16ShortUUID()
|
iguid = info.userId
|
sguid = evaluationId
|
erguid = rule?.guid
|
rulename = rule?.rulename
|
ruletype = rule?.ruletype?.toInt()
|
ertype = itemRule.ertype
|
esrguid = itemRule.guid
|
name = itemRule.itemname
|
value = itemRule.extension1 ?: "0"
|
extension1 = (itemRule.extension1 != null).toString()
|
}
|
|
private fun write2File(info: Info, evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule>,
|
rules: MutableList<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>) {
|
|
val heads = mutableListOf<Array<String>>()
|
val contents = mutableListOf<Array<Any>>()
|
topItems.forEach {
|
val cList = mutableListOf<Any>()
|
cList.add(it.itemname ?: "")
|
val array1 = mutableListOf<ExcelUtil.MyCell>()
|
val array2 = mutableListOf<ExcelUtil.MyCell>()
|
val array3 = mutableListOf<ExcelUtil.MyCell>()
|
for (r in rules) {
|
if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
|
array1.add(ExcelUtil.MyCell(r.first.itemname?:"", 0))
|
|
r.second.forEach { s ->
|
if (s.fatherid == r.first.guid) {
|
array2.add(ExcelUtil.MyCell(s.itemname?:"", 1))
|
array3.add(ExcelUtil.MyCell(s.extension1?:"", 1))
|
array1.last().rowSpan++
|
}
|
}
|
}
|
}
|
cList.add(array1.toTypedArray())
|
cList.add(array2.toTypedArray())
|
cList.add(array3.toTypedArray())
|
contents.add(cList.toTypedArray())
|
}
|
evaluations.forEach {
|
if ((it.ertype?.toInt() == 0)) {
|
val totalScoreList = mutableListOf<Any>()
|
totalScoreList.add("总分")
|
totalScoreList.add(it.resultscorebef ?: "0")
|
contents.add(totalScoreList.toTypedArray())
|
}
|
}
|
|
ExcelUtil.write2(heads, contents, workbook!!, info.userName ?: "未知用户")
|
}
|
|
private fun addToFile(contents: MutableList<Array<Any>>, info: Info, evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule>,
|
rules: MutableList<Pair<Evaluationsubrule, MutableList<Evaluationsubrule>>>) {
|
val cList = mutableListOf<Any>()
|
// FIXME: 2021/4/28 用户名是否添加账号
|
// cList.add("${info.userName}\t${info.userId}")
|
cList.add("${info.userName}")
|
//每一项具体得分
|
topItems.forEach {
|
for (r in rules) {
|
if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
|
// FIXME: 2021/4/25 决定是否写h3
|
// r.second.forEach {s ->
|
// cList.add(s.extension1 ?: "")
|
// }
|
cList.add(r.first.extension1?.toDoubleOrNull() ?: -99.0)
|
}
|
}
|
}
|
//总分和环信码
|
evaluations.forEach {
|
if ((it.ertype?.toInt() == 0)) {
|
cList.add(it.resultscorebef?.toDoubleOrNull() ?: -99.0)
|
val code = when (it.resultscorebef?.toIntOrNull() ?: 0) {
|
in 0..59 -> ExcelUtil.MyCell("红码", fontColor = HSSFColor.HSSFColorPredefined.RED.index)
|
in 60..89 -> ExcelUtil.MyCell("黄码", fontColor = HSSFColor.HSSFColorPredefined.GOLD.index)
|
in 90..100 -> ExcelUtil.MyCell("绿码", fontColor = HSSFColor.HSSFColorPredefined.BRIGHT_GREEN.index)
|
else -> ExcelUtil.MyCell("超出范围:${it.resultscoreaft}", fontColor = HSSFColor.HSSFColorPredefined.BLACK.index)
|
}
|
cList.add(code)
|
}
|
}
|
contents.add(cList.toTypedArray())
|
}
|
|
/**
|
* 生成最终得分表
|
*/
|
private fun finalScore(evaluation: Evaluation, year: Int, eMonth: Int, period: String) {
|
val overallEvaluation = OverallEvaluation().apply {
|
biGuid = evaluation.iguid
|
oeScore = evaluation.resultscorebef?.toIntOrNull()
|
oePublishTime = Date.from(LocalDateTime.of(year, eMonth + 1, 1, 0, 0).atZone(ZoneId.systemDefault()).toInstant())
|
oeUpdateTime = oePublishTime
|
oeSceneTypeId = SCENE_TYPE.value.toByte()
|
oeSceneType = SCENE_TYPE.des
|
oePeriod = period
|
oeCodeLevel = when (evaluation.resultscorebef?.toIntOrNull() ?: 0) {
|
in 0..59 -> 2
|
in 60..89 -> 1
|
in 90..100 -> 0
|
else -> 2
|
}
|
}
|
overallEvaluationMapper.insert(overallEvaluation)
|
}
|
}
|