feiyu02
2022-07-14 4c7e2d8f8d4a93f318ada0e728dbc370e7504e92
1. 自动评分优化;
2. 巡查汇总报告功能编写中
已修改23个文件
已添加4个文件
1933 ■■■■■ 文件已修改
src/main/kotlin/cn/flightfeather/supervision/business/Info.kt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/ScoreItem.kt 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_10.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_7.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_8.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/report/BaseTemplate.kt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/report/DataSource.kt 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/report/ReportUtil.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/storage/StAutoScore.kt 551 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/utils/Constant.kt 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/utils/ExcelUtil.kt 121 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/common/utils/FileUtil.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/MonitorobjectversionMapper.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/SubtaskMapper.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemlistService.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomainitemServiceImpl.kt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/MediafileServiceImpl.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemlistServiceImpl.kt 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SearchServiceImpl.kt 882 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/VersionServiceImpl.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ExcelConfigVo.kt 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ProblemChangeVo.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ProblemlistController.kt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ds1/SubtaskMapper.xml 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/cn/flightfeather/supervision/business/fume/AutoScoreTest.kt 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SearchServiceImplTest.kt 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/cn/flightfeather/supervision/business/Info.kt
@@ -1,10 +1,11 @@
package cn.flightfeather.supervision.business
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.domain.ds1.entity.Subtask
import java.time.LocalDateTime
class Info(
data class Info(
        //场景用户id
        val userId: String?,
        //飞羽环境中场景对应的用户id
@@ -14,9 +15,11 @@
        //场景名称
        val sceneName: String?,
        var sceneType: Constant.ScenseType,
        var year: Int,
        val month: Int,
        val period: Int,
        val sTime: LocalDateTime,
        val eTime: LocalDateTime
        var year: Int? = null,
        val month: Int? = null,
        val period: Int? = null,
        val sTime: LocalDateTime? = null,
        val eTime: LocalDateTime? = null,
        val subTask: Subtask? = null,
        val sceneIndex: Int? = null
)
src/main/kotlin/cn/flightfeather/supervision/business/ScoreItem.kt
@@ -84,13 +84,13 @@
        evaluationsubruleList.forEach {
            if (it.fatherid == id) {
                // æ ¹æ®è§„则对应的相关问题id,查找用户在当前时间段内是否有发生该问题,有则扣除相应的分数
                it.problemlist?.let {pId ->
                    problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                        createCriteria().andEqualTo("sguid", info.sceneId)
                            .andEqualTo("ptguid", pId)
                            .andGreaterThanOrEqualTo("time", info.sTime)
                            .andLessThan("time", info.eTime)
                    })?.takeIf { p-> p.isNotEmpty() }?.run {
                val pList = problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                    createCriteria().andEqualTo("sguid", info.sceneId)
                        .andGreaterThanOrEqualTo("time", info.sTime)
                        .andLessThan("time", info.eTime)
                }).map { p-> p.ptguid }
                it.problemlist?.split(",")?.forEach {pId ->
                    if (pList.contains(pId)) {
                        it.extension1 = (0 - (it.maxscore ?: 0)).toString()
                    }
                }
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_10.kt
@@ -38,8 +38,8 @@
     *      4.有环境违法行为且受到行政处罚
     */
    override fun otherProblem(size: Int): Int? {
        val s = Date.from(info.sTime.atZone(ZoneId.systemDefault()).toInstant())
        val e = Date.from(info.eTime.atZone(ZoneId.systemDefault()).toInstant())
        val s = Date.from(info.sTime?.atZone(ZoneId.systemDefault())?.toInstant())
        val e = Date.from(info.eTime?.atZone(ZoneId.systemDefault())?.toInstant())
        var i = 1
        when {
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_7.kt
@@ -73,7 +73,7 @@
     * @return true  å°è´¦å°‘量缺失或未及时记录更新
     */
    private fun condition1(c1: Int, c2: Int): Boolean {
        return c2 > 0 && c2 < c1 * info.period
        return c2 > 0 && c2 < c1 * (info.period ?: 0)
    }
    /**
src/main/kotlin/cn/flightfeather/supervision/business/fume/item/ScoreItem_8.kt
@@ -46,7 +46,7 @@
        eList.forEach {
            if (list.contains(it.first.guid)) {
                it.second.forEach {e ->
                    exemptionItemIdList.addAll(e.problemlist?.split(";") ?: emptyList())
                    exemptionItemIdList.addAll(e.problemlist?.split(",") ?: emptyList())
                }
            }
        }
@@ -54,7 +54,7 @@
    fun setExemptionProblem(list: List<Evaluationsubrule2>) {
        list.forEach {
            exemptionItemIdList.addAll(it.problemlist?.split(";") ?: emptyList())
            exemptionItemIdList.addAll(it.problemlist?.split(",") ?: emptyList())
        }
    }
src/main/kotlin/cn/flightfeather/supervision/business/report/BaseTemplate.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package cn.flightfeather.supervision.business.report
/**
 * æŠ¥å‘Šæ¨¡æ¿åŸºç±»
 */
abstract class BaseTemplate {
    //固定列组合
    //名称
    //基本信息
    //问题扣分分布
    //问题整改分布
    //监管详情
}
src/main/kotlin/cn/flightfeather/supervision/business/report/DataSource.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package cn.flightfeather.supervision.business.report
import cn.flightfeather.supervision.domain.ds1.entity.Problemlist
import cn.flightfeather.supervision.domain.ds1.entity.Problemtype
import cn.flightfeather.supervision.domain.ds1.entity.Scense
import cn.flightfeather.supervision.domain.ds1.entity.Subtask
/**
 * æŠ¥å‘Šæ‰€éœ€æºæ•°æ®
 * ç”ŸæˆæŠ¥å‘Šæ—¶ï¼Œæ‰€éœ€è¦çš„æ•°æ®æº
 */
class DataSource {
    private var subTask: Subtask? = null
    /**
     * æŒ‡å®šå½“前进行统计的主体对象
     */
    fun mainObj(subtask: Subtask) {
        this.subTask = subTask
    }
    //场景基本信息
    var scene: Scense? = null
    //问题类型
    var problemTypes = mutableListOf<Problemtype>()
    //具体的问题
    var problems = mutableListOf<Problemlist>()
}
src/main/kotlin/cn/flightfeather/supervision/business/report/ReportUtil.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package cn.flightfeather.supervision.business.report
/**
 * æŠ¥å‘Šç”Ÿæˆå·¥å…·
 */
class ReportUtil {
}
src/main/kotlin/cn/flightfeather/supervision/business/storage/StAutoScore.kt
@@ -2,7 +2,6 @@
import cn.flightfeather.supervision.business.Info
import cn.flightfeather.supervision.business.ScoreItem
import cn.flightfeather.supervision.business.fume.AutoScore3
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.common.utils.DateUtil
import cn.flightfeather.supervision.common.utils.ExcelUtil
@@ -30,16 +29,12 @@
 * å·¥åœ°è‡ªåŠ¨è¯„åˆ†
 */
@Component
class StAutoScore(val stScoreItem_1: ScoreItem) {
class StAutoScore(
    stScoreItem_1: ScoreItem,
    var sceneType: Constant.ScenseType = Constant.ScenseType.TYPE1, )
{
    companion object {
        private lateinit var instance: StAutoScore
        private val SCENE_TYPE = Constant.ScenseType.TYPE1
        private const val DISTRICT = "金山区"
    }
    @PostConstruct
    fun init() {
     instance = this
    }
    @Autowired
@@ -72,8 +67,14 @@
    @Autowired
    lateinit var taskMapper: TaskMapper
    @Autowired
    lateinit var inspectionMapper: InspectionMapper
    @Autowired
    lateinit var subtaskMapper: SubtaskMapper
    //决定是否写h3
    private val hasHead3 = false
    private val hasHead3 = true
    private var totalScore = 100//满分
@@ -85,31 +86,279 @@
    private val topItems = mutableListOf<Evaluationsubrule2>()
    // excel文档
    private var workbook = HSSFWorkbook()
    // æ–‡æ¡£è¡Œæ•°æ®
    private val rows = mutableListOf<Array<Any>>()
    init {
        itemList.add(stScoreItem_1)
    }
    fun go(_year: Int? = null, _month: Int? = null, _period: Int = 1) {
        val now = LocalDate.now()
        val year = _year ?: now.year
        val month = _month ?: now.monthValue
        val sMonth = DateUtil().getStartMonthByPeriod(month, _period) ?: 1
        val eMonth = sMonth + _period - 1
        val sTime = LocalDateTime.of(year, sMonth, 1, 0, 0)
        val eTime = sTime.plusMonths(_period.toLong())
        val period = "${year}/$sMonth-$eMonth"
    @PostConstruct
    fun init() {
        instance = this
    }
    /**
     * æ€»ä»»åŠ¡æ‰“åˆ†
     * æ ¹æ®æ€»ä»»åŠ¡ï¼Œå¯¹ä¸‹å±žæ‰€æœ‰çš„å·¡æŸ¥ä»»åŠ¡æŒ¨ä¸ªæ‰“åˆ†
     * @param topTaskId æ€»ä»»åŠ¡id
     */
    fun topTaskGrade(topTaskId:String) {
        rows.clear()
        subtaskMapper.selectByTopTask2(topTaskId, sceneType.value.toInt()).forEach {
//            sceneGrade(it)
            sceneGradeToFile(it)
        }
        toFile()
    }
    /**
     * å•场景打分
     * @param subtask å·¡æŸ¥ä»»åŠ¡
     */
    fun sceneGrade(subtask: Subtask) {
        // èŽ·å–è¯„åˆ†è§„åˆ™
        getScoreItem()
        val info = itemGrade(subtask)
        val result = totalGrade(info) ?: return
        toDb(info, result)
//        addToFile(rows, info, result.first)
//        toFile()
    }
    fun sceneGradeToFile(subtask: Subtask) {
        // èŽ·å–è¯„åˆ†è§„åˆ™
        getScoreItem()
        val info = itemGrade(subtask)
        val result = totalGrade(info) ?: return
        addToFile(rows, info, result.first)
    }
    /**
     * æ¡ç›®æ‰“分
     */
    private fun itemGrade(subtask: Subtask): Info {
        // è§„则条目得分初始化
        topItems.forEach { s -> s.extension1 = null }
        rules.forEach { p ->
            p.first.extension1 = null
            p.second.forEach { e -> e.extension1 = null }
        }
        // èŽ·å–é£žç¾½ç›‘ç®¡ç³»ç»Ÿç”¨æˆ·ä¿¡æ¯
        val userInfo = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
            createCriteria().andEqualTo("dGuid", subtask.scenseid)
        })?.takeIf { l -> l.isNotEmpty() }?.get(0)
        // èŽ·å–é£žç¾½çŽ¯å¢ƒç³»ç»Ÿç”¨æˆ·ä¿¡æ¯
        val tzUserId = userMapMapper.selectByExample(Example(UserMap::class.java).apply {
            createCriteria().andEqualTo("svUserId", userInfo?.guid)
        })?.takeIf { m -> m.isNotEmpty() }?.get(0)?.tzUserId
        val scene = scenseMapper.selectByPrimaryKey(subtask.scenseid)
        val info =
            Info(userInfo?.guid, tzUserId, subtask.scenseid, subtask.scensename, sceneType, subTask = subtask, sceneIndex = scene.index)
        /** 1. æ ¹æ®è¯„分规则对应的问题自动判断是否扣分***************************************************************/
        // èŽ·å–è¯¥æ¬¡å·¡æŸ¥ä»»åŠ¡ä¸‹çš„æ‰€æœ‰é—®é¢˜
        val pList = problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
            createCriteria().andEqualTo("stguid", info.subTask?.stguid)
        }).map { it.ptguid }
        // è®¡ç®—每条评分规则的得分
        rules.forEach { r ->
            // è¯„分条目
            val rule = r.first
            // å…·ä½“评分选项
            val subRule = r.second
            subRule.forEach { sr ->
                sr.problemlist?.split(",")?.forEach { pId ->
                    if (pList.contains(pId)) {
                        sr.extension1 = (0 - (sr.maxscore ?: 0)).toString()
                    }
                }
            }
            var total: Int? = null
            subRule.forEach { sr ->
                if (!sr.extension1.isNullOrBlank()) {
                    total = (total ?: 0) + sr.extension1!!.toInt()
                }
            }
            if (total == null) {
                rule.extension1 = "0"
            } else {
                val s = if (abs(total!!) > rule.maxscore!!) {
                    0 - rule.maxscore!!
                } else {
                    total
                }
                rule.extension1 = s.toString()
            }
        }
        /** 2.部分有特殊评分逻辑的规则进行计算*************************************************************************/
        itemList.forEach { item -> item.execute2(info, rules) }
        /** 3. è¡¥å…¨å„上级评分项的计分*************************************************************************/
        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
                    // é™åˆ¶æœ€é«˜æ‰£åˆ†
                    if (abs(s) > (t.maxscore ?: 0)) {
                        s = 0 - (t.maxscore ?: 0)
                    }
                    t.extension1 = s.toString()
                    break
                }
            }
        }
        return info
    }
    /**
     * è®¡ç®—总分
     */
    private fun totalGrade(info: Info): Pair<Evaluation, List<Itemevaluation>>? {
        /** 4. è®¡ç®—总分*************************************************************************/
        val scene = scenseMapper.selectByPrimaryKey(info.subTask?.scenseid) ?: return null
        val inspection = inspectionMapper.selectByExample(Example(Inspection::class.java).apply {
            createCriteria().andEqualTo("stguid", info.subTask?.stguid)
        })?.takeIf { it.isNotEmpty() }?.let { it[0] }
        var total = 0//总扣除的分数
        topItems.forEach top@{ top ->
            total += top.extension1?.toIntOrNull() ?: 0
        }
        val evaluation = Evaluation()
        baseRules.forEach {
            evaluation.apply {
                guid = UUIDGenerator.generate16ShortUUID()
                iguid = inspection?.guid
                stguid = info.subTask?.stguid
                sguid = info.subTask?.scenseid
                scensetypeid = scene.typeid
                scensetype = scene.type
                subscensetypeid = scene.scensesubtypeid
                subscensetype = scene.scensesubtype
                ertype = it.ruletype?.toByte()
                provincecode = scene.provincecode
                provincename = scene.provincename
                citycode = scene.citycode
                cityname = scene.cityname
                districtcode = scene.districtcode
                districtname = scene.districtname
                towncode = scene.towncode
                townname = scene.townname
                scensename = scene.name
                scenseaddress = scene.location
                evaluatetime = Date()
                evaluatorguid = "admin"
                evaluatorusername = "admin"
                evaluatorrealname = "admin"
                resultscorebef = (totalScore - abs(total)).toString()
                createdate = Date()
                updatedate = Date()
            }
        }
        //子项具体得分
        val itemevaluationList = mutableListOf<Itemevaluation>()
        topItems.forEach { subRule ->
            val item = newItemEvaluation(info, subRule, inspection)
            itemevaluationList.add(item)
        }
        rules.forEach { p ->
            if (p.first.ertype != 2) {
                val item = newItemEvaluation(info, p.first, inspection)
                itemevaluationList.add(item)
            }
            p.second.forEach { r ->
                val item1 = newItemEvaluation(info, r, inspection)
                itemevaluationList.add(item1)
            }
        }
        return Pair(evaluation, itemevaluationList)
    }
    /**
     * å°†è¯„分记录输出至数据库
     */
    private fun toDb(info: Info, p: Pair<Evaluation, List<Itemevaluation>>) {
        //去除已有记录
        evaluationMapper.deleteByExample(Example(Evaluation::class.java).apply {
            createCriteria().andEqualTo("stguid", info.subTask?.stguid)
        })
        itemevaluationMapper.deleteByExample(Example(Itemevaluation::class.java).apply {
            createCriteria().andEqualTo("stguid", info.subTask?.stguid)
        })
        //写入数据库
        evaluationMapper.insert(p.first)
        p.second.forEach { il -> itemevaluationMapper.insert(il) }
    }
    /**
     * è½¬æ¢ä¸€æ¡è¯„分至excel中的一行
     */
    private fun addToFile(contents: MutableList<Array<Any>>, info: Info, evaluations: Evaluation) {
        val cList = mutableListOf<Any>()
        // FIXME: 2021/4/28 ç”¨æˆ·åæ˜¯å¦æ·»åŠ è´¦å·
//        cList.add("${info.userName}\t${info.userId}")
        cList.add(info.sceneIndex ?: -99)
        cList.add("")
        cList.add("${info.sceneName}")
        //每一项具体得分
        topItems.forEach {
            for (r in rules) {
                if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
                    // FIXME: 2021/4/25 å†³å®šæ˜¯å¦å†™h3
                    if (hasHead3) {
                        r.second.forEach { s ->
                            cList.add(s.extension1?.toInt() ?: "")
                        }
                    } else {
                        cList.add(r.first.extension1?.toInt() ?: "")
                    }
                }
            }
        }
        //总分和环信码
        evaluations.let {
            cList.add(it.resultscorebef?.toDoubleOrNull() ?: .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())
    }
    /**
     * å°†è¯„分记录输出为excel
     */
    private fun toFile() {
        val contents = mutableListOf<Array<Any>>()
        val h1 = mutableListOf<ExcelUtil.MyCell>()
        h1.add(ExcelUtil.MyCell(""))
        h1.add(ExcelUtil.MyCell("表单编号", if (hasHead3) 3 else 2))
        h1.add(ExcelUtil.MyCell("唯一序号", if (hasHead3) 3 else 2))
        h1.add(ExcelUtil.MyCell("场景名称", if (hasHead3) 3 else 2))
        val h2 = mutableListOf<ExcelUtil.MyCell>()
        h2.add(ExcelUtil.MyCell(""))
        h2.add(ExcelUtil.MyCell(""))
        h2.add(ExcelUtil.MyCell(""))
        val h3 = mutableListOf<String>()
        h3.add("")
        h3.add("")
        h3.add("")
        topItems.forEach {
            h1.add(ExcelUtil.MyCell(it.itemname ?: "", 1, 0))
@@ -130,220 +379,32 @@
                }
            }
        }
        // FIXME: 2021/4/25 å†³å®šæ˜¯å¦å†™h3
        // å†³å®šæ˜¯å¦å†™h3
        if (hasHead3) {
            h1.add(ExcelUtil.MyCell("总分", 3, 1))
            h1.add(ExcelUtil.MyCell("环信码", 3, 1))
            h1.add(ExcelUtil.MyCell("防治规范性", 3, 1))
        } else {
            h1.add(ExcelUtil.MyCell("总分", 2, 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
        // å†³å®šæ˜¯å¦å†™h3
        if (hasHead3) {
            contents.add(h3.toTypedArray())
        }
        /** 2. ç­›é€‰æ‰“分场景*************************************************************************/
        val tasks = taskMapper.selectByExample(Example(Task::class.java).apply {
            createCriteria().andEqualTo("levelnum", 2)
                .andEqualTo("districtname", DISTRICT)
                .andGreaterThanOrEqualTo("starttime", sTime)
                .andLessThanOrEqualTo("endtime", eTime)
        })
        val mList = if (tasks.isNotEmpty()) {
            val taskId = tasks[0].tguid
            monitorobjectversionMapper.selectByExample(Example(Monitorobjectversion::class.java).apply {
                createCriteria().andEqualTo("tid", taskId)
            })
        } else {
            emptyList()
        }
//        val sceneList = scenseMapper.selectByExample(Example(Scense::class.java).apply {
//            createCriteria().andEqualTo("typeid", SCENE_TYPE.value.toByte())
//                .andEqualTo("districtname", DISTRICT)
//                .andNotEqualTo("extension1", '0')
////            createCriteria().andEqualTo("guid", "XcRAQtiD4tTU90sA")
//        })
        /** 3. å¾ªçŽ¯å¤„ç†æ¯ä¸ªåœºæ™¯ï¼Œç»™æ¯ä¸ªåœºæ™¯æ‰“åˆ†*************************************************************************/
        val sceneList = listOf(
            "q4qOX4kU0aa8J6W2",
            "Syu177gGk1dkiFD1",
            "7GQ53boTPxIPKFv5",
            "zIAoNkridReTEFs9",
            "q4qOX4kU0aa8J6W2",
            "7vz7deflv1bXfVLq",
            "F1f4FXrQ8Knd9UuS",
            "5wufBlqzNPy5z9hs",
            "y0t0XulzkNILtEr3",
            "F7oulQiTCyVZAoJY"
        )
        mList.forEach {
            if (!sceneList.contains(it.sguid)) return@forEach
            //筛选所需要的场景类型
            val scene = scenseMapper.selectByPrimaryKey(it.sguid)
            if (scene.type != SCENE_TYPE.text) return@forEach
            topItems.forEach { s -> s.extension1 = null }
            rules.forEach { p ->
                p.first.extension1 = null
                p.second.forEach { e -> e.extension1 = null }
            }
            val userInfo = userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
                createCriteria().andEqualTo("dGuid", it.sguid)
            })?.takeIf { l -> l.isNotEmpty() }?.get(0)
            val tzUserId = userMapMapper.selectByExample(Example(UserMap::class.java).apply {
                createCriteria().andEqualTo("svUserId", userInfo?.guid)
            })?.takeIf { m -> m.isNotEmpty() }?.get(0)?.tzUserId
            val info =
                Info(userInfo?.guid, tzUserId, it.sguid, it.sensename, SCENE_TYPE, year, sMonth, _period, sTime, eTime)
            /** 1. æ ¹æ®è¯„分规则对应的问题自动判断是否扣分***************************************************************/
            rules.forEach {r ->
                // è¯„分条目
                val rule = r.first
                // å…·ä½“评分选项
                val subRule = r.second
                subRule.forEach {sr ->
                    sr.problemlist?.let {pId ->
                        problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                            createCriteria().andEqualTo("sguid", info.sceneId)
                                .andEqualTo("ptguid", pId)
                                .andGreaterThanOrEqualTo("time", info.sTime)
                                .andLessThan("time", info.eTime)
                        })?.takeIf { p-> p.isNotEmpty() }?.run {
                            sr.extension1 = (0 - (sr.maxscore ?: 0)).toString()
                        }
                    }
                }
                var total: Int? = null
                subRule.forEach {sr ->
                    if (!sr.extension1.isNullOrBlank()) {
                        total = (total ?: 0) + sr.extension1!!.toInt()
                    }
                }
                if (total == null) {
                    rule.extension1 = "0"
                } else {
                    val s = if (abs(total!!) > rule.maxscore!!) {
                        0 - rule.maxscore!!
                    } else {
                        total
                    }
                    rule.extension1 = s.toString()
                }
            }
            /** 2.部分有特殊评分逻辑的规则进行计算*************************************************************************/
            itemList.forEach { item-> item.execute2(info, rules) }
            /** 3. è¡¥å…¨å„上级评分项的计分*************************************************************************/
            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
                        // é™åˆ¶æœ€é«˜æ‰£åˆ†
                        if (abs(s) > (t.maxscore ?: 0)) {
                            s = 0 - (t.maxscore ?: 0)
                        }
                        t.extension1 = s.toString()
                        break
                    }
                }
            }
            /** 4. è®¡ç®—总分*************************************************************************/
            var total = 0//总扣除的分数
            topItems.forEach top@{ top ->
                total += top.extension1?.toIntOrNull() ?: 0
            }
            val evaluationList = mutableListOf<Evaluation>()
            var evaluationId: String? = null
            baseRules.forEach {
                val evaluation = 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)
//            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
            // å†™å…¥æ•°æ®åº“
//            if (r > 0) {
//                evaluationList.forEach { el -> evaluationMapper.insert(el) }
//                itemevaluationList.forEach { il -> itemevaluationMapper.insert(il) }
//                for (e in evaluationList) {
//                    if (e.ertype?.toInt()?.equals(0) == true) {
//                        finalScore(e, year, eMonth, period)
//                        break
//                    }
//                }
//            }
        }
        rows.sortBy { it[0] as Int }
        contents.addAll(rows)
        // å†™å…¥æ–‡æ¡£
        val fileName = "${year}å¹´${if (_period == 1) "${sMonth}月" else "${sMonth}-${eMonth}月"}${SCENE_TYPE.text}自动评分-${DateUtil().DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
//        val filePath = "E:\\工作\\开发\\第三方监管app\\自动评分\\工地\\$fileName"
        val filePath = "C:\\work\\工作\\第三方监管\\自动评分\\${SCENE_TYPE.text}\\$fileName"
        val fileName = "${sceneType.text}自动评分-${DateUtil().DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
        val filePath = "C:\\work\\工作\\第三方监管\\自动评分\\${sceneType.text}\\$fileName"
        val file = File(filePath)
        if (!file.parentFile.exists()) {
            file.parentFile.mkdirs()
        }
        val out = FileOutputStream(File(filePath))
        ExcelUtil.write(emptyList(), contents, workbook)
        workbook.write(out)
@@ -358,11 +419,12 @@
    private fun getScoreItem() {
        this.rules.clear()
        baseRules.clear()
        topItems.clear()
        val rule = evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
            createCriteria()
                .andEqualTo("tasktypeid", 99)
                .andEqualTo("scensetypeid", SCENE_TYPE.value.toByte())
                .andEqualTo("scensetypeid", sceneType.value.toByte())
        })
        if (rule.isNotEmpty()) {
            baseRules.addAll(rule)
@@ -403,14 +465,14 @@
                    this.rules.add(Pair(temp, tempSubRules))
                }
            }
//            this.totalScore = t
            this.totalScore = t
        }
    }
    /**
     * ç”Ÿæˆæ–°çš„一条评分记录
     */
    private fun newItemEvaluation(info: Info, itemRule: Evaluationsubrule2, evaluationId: String?) = cn.flightfeather.supervision.domain.ds1.entity.Itemevaluation()
    private fun newItemEvaluation(info: Info, itemRule: Evaluationsubrule2, inspection: Inspection?) = Itemevaluation()
        .apply {
            var rule: Evaluationrule? = null
            for (r in baseRules) {
@@ -420,8 +482,10 @@
                }
            }
            ieguid = UUIDGenerator.generate16ShortUUID()
            iguid = info.userId
            sguid = evaluationId
            iguid = inspection?.guid
            stguid = info.subTask?.stguid
            sguid = info.subTask?.scenseid
            sensename = info.subTask?.scensename
            erguid = rule?.guid
            rulename = rule?.rulename
            ruletype = rule?.ruletype?.toInt()
@@ -431,41 +495,4 @@
            value = itemRule.extension1 ?: "0"
            extension1 = (itemRule.extension1 != null).toString()
        }
    private fun addToFile(contents: MutableList<Array<Any>>, info: Info, evaluations: List<Evaluation>, topItems: MutableList<Evaluationsubrule2>,
                          rules: MutableList<Pair<Evaluationsubrule2, MutableList<Evaluationsubrule2>>>) {
        val cList = mutableListOf<Any>()
        // FIXME: 2021/4/28 ç”¨æˆ·åæ˜¯å¦æ·»åŠ è´¦å·
//        cList.add("${info.userName}\t${info.userId}")
        cList.add("${info.sceneName}")
        //每一项具体得分
        topItems.forEach {
            for (r in rules) {
                if (r.first.fatherid == it.guid || r.first.guid == it.guid) {
                    // FIXME: 2021/4/25 å†³å®šæ˜¯å¦å†™h3
                    if (hasHead3) {
                        r.second.forEach {s ->
                            cList.add(s.extension1 ?: "")
                        }
                    } else {
                        cList.add(r.first.extension1?.toDoubleOrNull() ?: .0)
                    }
                }
            }
        }
        //总分和环信码
        evaluations.forEach {
            if ((it.ertype?.toInt() == 2)) {
                cList.add(it.resultscorebef?.toDoubleOrNull() ?: .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())
    }
}
src/main/kotlin/cn/flightfeather/supervision/common/utils/Constant.kt
@@ -52,14 +52,25 @@
        const val CHANGE_CHECK_PASS = "change_pass"//整改通过
        const val CHANGE_CHECK_FAIL = "change_fail"//整改未通过
        //问题整改
        const val LOCAL_CHANGE = "现场整改"
        const val PROMISE_CHANGE = "承诺整改"
        const val UN_PROMISE_CHANGE = "未承诺整改"
        const val PROBLEM_DELETED = "deleted"//问题删除
//        const val DEFAULT_FILE_PATH = "E:/02product/04supervision_ii"
//        const val DEFAULT_FILE_PATH = "D:/02product/04supervision_ii"
//        const val DEFAULT_FILE_PATH = "target"
        const val DEFAULT_FILE_PATH = "D:/02product/04supervision"
        // å·¥åœ°é—®é¢˜ä½ç½®
        const val INDUSTRY_LOCATION_ID = "JxTIFYjzUsAiOmqT"
        // ç å¤´ã€å †åœºé—®é¢˜ä½ç½®
        const val WHARF_LOCATION_ID = "mUeYoflgS4mOVBA2"
        // æ°´æ³¥æ…拌站
        const val MIX_LOCATION_ID = "yKbiSAja1CyyBjlS"
        // å †åœº
        const val STORAGE_YARD_LOCATION_ID = "AxYp8idrARnnep4H"
        // é¤é¥®é—®é¢˜ä½ç½®
        const val RESTAURANT_LOCATION_ID = "bMpvxuqHlB1CTYfh"
        // æ±½ä¿®é—®é¢˜ä½ç½®
src/main/kotlin/cn/flightfeather/supervision/common/utils/ExcelUtil.kt
@@ -24,19 +24,20 @@
    /**
     * è‡ªåŠ¨å¤„ç†è¡Œåˆå¹¶æ•°æ®
     */
    fun write(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
    fun write(heads: List<Array<Any>>, contents: MutableList<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
        val sheet = workbook.createSheet(sheetName)
        var rowIndex = 0
        heads.forEach {
            val rows = sheet.createRow(rowIndex)
            for (i in it.indices) {
                rows.createCell(i).setCellValue(it[i])
            }
            rowIndex++
        }
//        heads.forEach {
//            val rows = sheet.createRow(rowIndex)
//            for (i in it.indices) {
//                rows.createCell(i).setCellValue(it[i])
//            }
//            rowIndex++
//        }
        contents.addAll(0, heads)
        contents.forEach {
            val maxRow = getMaxRows(it)
@@ -100,9 +101,12 @@
                        println("write1-1: ${c.text};($rowIndex, ${col})")
                    }
                    is String -> {
                        rows.createCell(col).setCellValue(c)
                        println("write1-2: ${c};($rowIndex, ${col})")
                        if (c.isNotBlank()) {
                            rows.createCell(col).setCellValue(c)
                            println("write1-2: ${c};($rowIndex, ${col})")
                        }
                    }
                    is Int -> rows.createCell(col).setCellValue(c.toDouble())
                    is Double -> rows.createCell(col).setCellValue(c)
                    is Boolean -> rows.createCell(col).setCellValue(c)
                    is Date -> rows.createCell(col).setCellValue(c)
@@ -150,9 +154,12 @@
                                println("write2-1: ${c.text};($_rowIndex, ${map.key})")
                            }
                            is String -> {
                                rows.createCell(map.key).setCellValue(c)
                                println("write2-2: ${c};($_rowIndex, ${map.key})")
                                if (c.isNotBlank()) {
                                    rows.createCell(map.key).setCellValue(c)
                                    println("write2-2: ${c};($_rowIndex, ${map.key})")
                                }
                            }
                            is Int -> rows.createCell(map.key).setCellValue(c.toDouble())
                            is Double -> rows.createCell(map.key).setCellValue(c)
                            is Boolean -> rows.createCell(map.key).setCellValue(c)
                            is Date -> rows.createCell(map.key).setCellValue(c)
@@ -174,102 +181,16 @@
    /**
     * è‡ªåŠ¨å¤„ç†è¡Œåˆå¹¶æ•°æ®
     */
    fun write2(out: OutputStream, heads: List<String>, contents: List<Array<Any>>): String {
    fun write2(out: OutputStream, heads: List<Array<Any>>, contents: MutableList<Array<Any>>) {
        val workbook = HSSFWorkbook()
        val sheet = workbook.createSheet("sheet1")
        write(heads, contents, workbook)
        var rowIndex = 0
        if (heads.isNotEmpty()) {
            val rows = sheet.createRow(rowIndex)
            for (i in 0 until heads.size) {
                rows.createCell(i).setCellValue(heads[i])
            }
            rowIndex++
        }
        contents.forEach {
            val maxRow = getMaxRows(it)
            var rows = sheet.createRow(rowIndex)
            val arrayMap = mutableMapOf<Int, Array<*>>()
            for (i in it.indices) {
                val cell = it[i]
                var rowspan = maxRow//合并的行的跨度
                val c =
                        if (cell is Array<*>) {
                            //当数据为数组时,需要根据最大行数重新计算该单元格的行跨度
                            arrayMap[i] = cell
                            rowspan = maxRow / if(cell.size==0) 1 else cell.size
                            if (rowspan > 1) {
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            if (cell.isEmpty()) {
                                ""
                            } else {
                                cell[0]
                            }
                        } else {
                            //当数据不是数组时,需要按最大行数合并单元格
                            if (rowspan > 1) {
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            cell
                        }
                when (c) {
                    is String -> rows.createCell(i).setCellValue(c)
                    is Double -> rows.createCell(i).setCellValue(c)
                    is Boolean -> rows.createCell(i).setCellValue(c)
                    is Date -> rows.createCell(i).setCellValue(c)
                    is Calendar -> rows.createCell(i).setCellValue(c)
                    is LocalDate -> rows.createCell(i).setCellValue(c)
                }
            }
            for (i in 1 until maxRow) {
                rowIndex++
                rows = sheet.createRow(rowIndex)
                arrayMap.forEach {map ->
                    val array = map.value
                    if (i < array.size) {
                        val rowspan = maxRow / array.size
                        if (rowspan > 1) {
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                        }
                        val c = array[i]
                        when (c) {
                            is String -> rows.createCell(map.key).setCellValue(c)
                            is Double -> rows.createCell(map.key).setCellValue(c)
                            is Boolean -> rows.createCell(map.key).setCellValue(c)
                            is Date -> rows.createCell(map.key).setCellValue(c)
                            is Calendar -> rows.createCell(map.key).setCellValue(c)
                            is LocalDate -> rows.createCell(map.key).setCellValue(c)
                        }
                    }
                }
            }
            rowIndex++
        }
        val fileName = "${DateUtil().DateToString(Date(), "yyyy-MM-dd hh:mm:ss")}.xls"
        val filePath = "${Constant.DEFAULT_FILE_PATH}/files/$fileName"
        val xlsFile = File(filePath)
        if (!xlsFile.parentFile.exists()) {
            xlsFile.parentFile.mkdirs()
        }
//        val xlsStream = FileOutputStream(xlsFile)
        workbook.write(out)
        workbook.close()
        out.flush()
        out.close()
        return fileName
    }
    private fun getMaxRows(rowArray: Array<Any>): Int {
src/main/kotlin/cn/flightfeather/supervision/common/utils/FileUtil.kt
@@ -7,7 +7,7 @@
class FileUtil {
object FileUtil {
    @Throws(Exception::class)
    fun uploadFile(file: ByteArray, filePath: String, fileName: String) {
        val targetFile = File(filePath)
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/MonitorobjectversionMapper.kt
@@ -3,7 +3,12 @@
import cn.flightfeather.supervision.domain.ds1.entity.Monitorobjectversion
import cn.flightfeather.supervision.domain.util.MyMapper
import org.apache.ibatis.annotations.Mapper
import org.apache.ibatis.annotations.Select
@Mapper
interface MonitorobjectversionMapper:MyMapper<Monitorobjectversion> {
    @Select("select b.S_GUID from sm_t_monitorobjectversion as a left join sm_t_scense as b on a.S_GUID = b.S_GUID" +
            " where a.T_ID = #{param1} and b.S_TypeID = #{param2}")
    fun getSceneByType(topTaskId: String, sceneTypeId: Int): List<String>
}
src/main/kotlin/cn/flightfeather/supervision/domain/ds1/mapper/SubtaskMapper.kt
@@ -16,4 +16,6 @@
    fun getSubtask2(updateTime: Date?, updateTime2: Date?, districtCode: String, scenseTypeId: Byte?, planStartTime: Date?, planEndTime: Date?): List<SubTaskSearchResultVo2>
    fun selectByTopTask(topTaskId: String, startTime: String, endTime: String, sceneTypeId: Int? = null): List<SubtaskVo>
    fun selectByTopTask2(topTaskId: String, sceneTypeId: Int? = null): List<Subtask>
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/ProblemlistService.kt
@@ -42,4 +42,6 @@
    fun check(pId: String, action: Byte, remark: String, userId: String, userName: String): BaseResponse<String>
    fun newProblem(problem: String, files: Array<MultipartFile>): BaseResponse<String>
    fun changeProblem(problemId: String, files: Array<MultipartFile>): BaseResponse<String>
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/DomainitemServiceImpl.kt
@@ -83,6 +83,9 @@
    override fun getLocation(sceneType: Int): List<Domainitem> {
        val lId = when (sceneType.toString()) {
            Constant.ScenseType.TYPE1.value -> Constant.INDUSTRY_LOCATION_ID
            Constant.ScenseType.TYPE2.value -> Constant.WHARF_LOCATION_ID
            Constant.ScenseType.TYPE14.value -> Constant.STORAGE_YARD_LOCATION_ID
            Constant.ScenseType.TYPE3.value -> Constant.MIX_LOCATION_ID
            Constant.ScenseType.TYPE5.value -> Constant.RESTAURANT_LOCATION_ID
            Constant.ScenseType.TYPE6.value -> Constant.Vehicle_LOCATION_ID
            else -> Constant.INDUSTRY_LOCATION_ID
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/MediafileServiceImpl.kt
@@ -79,7 +79,7 @@
                val filePath = "${Constant.DEFAULT_FILE_PATH}/images/$path/"
                try {
                    //调用文件保存方法
                    FileUtil().uploadFile(image.bytes, filePath, fileName!!)
                    FileUtil.uploadFile(image.bytes, filePath, fileName!!)
                } catch (e: Exception) {
                    // TODO: handle exception
                }
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/ProblemlistServiceImpl.kt
@@ -21,7 +21,9 @@
import java.text.SimpleDateFormat
import javax.annotation.Resource
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
@@ -478,7 +480,7 @@
            val filePath = "${Constant.DEFAULT_FILE_PATH}/images/$path/"
            try {
                //调用文件保存方法
                FileUtil().uploadFile(image.bytes, filePath, fileName)
                FileUtil.uploadFile(image.bytes, filePath, fileName)
            } catch (e: Exception) {
                // TODO: handle exception
            }
@@ -486,4 +488,60 @@
        return BaseResponse(true)
    }
    override fun changeProblem(problemId: String, files: Array<MultipartFile>): BaseResponse<String> {
        // æ›´æ–°é—®é¢˜
        val p = problemlistMapper.selectByPrimaryKey(problemId) ?: return BaseResponse(false, "问题不存在")
        p.apply {
            ischanged = true
            changedtime = Date()
            extension3 = Constant.CHANGE_UNCHECKED
            val today = LocalDate.now()
            val pTime = LocalDateTime.ofInstant(time?.toInstant(), ZoneId.systemDefault()).toLocalDate()
            changecatalog = if (p.extension1 != null) {
                if (today.isAfter(pTime)) {
                    Constant.PROMISE_CHANGE
                } else {
                    Constant.LOCAL_CHANGE
                }
            } else {
                Constant.UN_PROMISE_CHANGE
            }
        }
        problemlistMapper.updateByPrimaryKey(p)
        // ä¿å­˜å›¾ç‰‡
        val now = LocalDateTime.now()
        val mediaFiles = mediafileMapper.selectByExample(Example(Mediafile::class.java).apply {
            createCriteria().andEqualTo("businessguid", p.guid)
                .andEqualTo("businesstypeid", 1)
                .andEqualTo("ischanged", false)
        })
        if (mediaFiles.isEmpty()) return BaseResponse(false, "场景问题数量为0,无法整改")
        val m = mediaFiles[0]
        m.path = m.path + "整改/"
        m.savetime = Date()
        m.ischanged = true
        for (image in files) {
            m.apply {
                guid = UUIDGenerator.generate16ShortUUID()
                description = p.problemname + " " + p.location + " æ•´æ”¹ " + UUIDGenerator.generateUUID(4) + ".jpg"
            }
            mediafileMapper.insert(m)
            val path = m.extension1
            val fileName = m.guid + ".jpg"
//            val filePath = "E:\\work\\第三方监管app\\自动评分\\餐饮\\"
            val filePath = "${Constant.DEFAULT_FILE_PATH}/images/$path"
            try {
                //调用文件保存方法
                FileUtil.uploadFile(image.bytes, filePath, fileName)
            } catch (e: Exception) {
                println(e)
            }
        }
        return BaseResponse(true)
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SearchServiceImpl.kt
@@ -25,28 +25,35 @@
    val userinfoMapper: UserinfoMapper,
    val subtaskMapper: SubtaskMapper,
    val scenseMapper: ScenseMapper,
    val sceneConstructionSiteMapper: SceneConstructionSiteMapper,
    val sceneMixingPlantMapper: SceneMixingPlantMapper,
    val sceneStorageYardMapper: SceneStorageYardMapper,
    val sceneWharfMapper: SceneWharfMapper,
    val problemlistMapper: ProblemlistMapper,
    val problemtypeMapper: ProblemtypeMapper,
    val townMapper: TownMapper,
    val mediafileMapper: MediafileMapper,
    val scoreMapper: ScoreMapper,
    val inspectionMapper: InspectionMapper,
    val taskMapper: TaskMapper
): SearchService {
    val taskMapper: TaskMapper,
    val monitorobjectversionMapper: MonitorobjectversionMapper
) : SearchService {
    private val dateUtil = DateUtil()
    override fun writeToFile(config: ExcelConfigVo) {
        val fileName = "e:/${DateUtil().DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
        val fileName = "target/${dateUtil.DateToString(Date(), "yyyy-MM-ddhhmmss")}.xls"
        val out = FileOutputStream(fileName)
        val heads = getTableTitles()
        val contents = getTableContents(config)
        ExcelUtil.write2(out, heads, contents)
//        val heads = getTableTitles(config.sceneType, config.districtCode)
//        val contents = getTableContents(config, heads.size)
        val r = getTable(2, config)
        ExcelUtil.write2(out, r.first, r.second)
    }
    override fun getExcel(config: ExcelConfigVo, response: HttpServletResponse): HttpServletResponse {
        val fileName = "${DateUtil().DateToString(Date(), "yyyy-MM-dd hh:mm:ss")}.xls"
        val fileName = "${dateUtil.DateToString(Date(), "yyyy-MM-dd hh:mm:ss")}.xls"
        response.apply {
            setHeader("Content-Disposition", "attachment;filename=$fileName")
            setHeader("fileName", fileName)
@@ -56,18 +63,18 @@
            setDateHeader("Expires", 0)
        }
        val heads = getTableTitles()
        val contents = getTableContents(config)
//        val heads = getTableTitles(config.sceneType, config.districtCode)
//        val contents = getTableContents(config, heads.size)
        val r = getTable(1, config)
        val out = response.outputStream
        ExcelUtil.write2(out, heads, contents)
        ExcelUtil.write2(out, r.first, r.second)
        return response
    }
    override fun getSubTaskDetail(config: ExcelConfigVo): SubTaskTableVo {
        val titles = getTableTitles2()
        val content = getTableContents2(config)
        val titles = getTableTitles(config.sceneType, config.districtCode)
        val content = getTableContents(config, titles.size)
        return SubTaskTableVo(titles, content)
    }
@@ -94,19 +101,19 @@
                }
            } else {
                createCriteria()
                        .andEqualTo("tguid", config.topTaskGuid)
                        .andGreaterThanOrEqualTo("planstarttime", config.startTime)
                        .andLessThanOrEqualTo("planendtime", config.endTime).apply {
                            config.provinceCode?.let {
                                andEqualTo("provincecode", it)
                            }
                            config.cityCode?.let {
                                andEqualTo("citycode", it)
                            }
                            config.districtCode?.let {
                                andEqualTo("districtcode", it)
                            }
                    .andEqualTo("tguid", config.topTaskGuid)
                    .andGreaterThanOrEqualTo("planstarttime", config.startTime)
                    .andLessThanOrEqualTo("planendtime", config.endTime).apply {
                        config.provinceCode?.let {
                            andEqualTo("provincecode", it)
                        }
                        config.cityCode?.let {
                            andEqualTo("citycode", it)
                        }
                        config.districtCode?.let {
                            andEqualTo("districtcode", it)
                        }
                    }
            }
            orderBy("planstarttime")
        }
@@ -153,7 +160,7 @@
        }
        //建立第一层目录,包含所有的任务
        val time = DateUtil().DateToString(Date(), "yyyy-MM-dd_HH-mm-ss")
        val time = dateUtil.DateToString(Date(), "yyyy-MM-dd_HH-mm-ss")
        var basePath = Constant.DEFAULT_FILE_PATH + File.separator + "images" + File.separator + "temp" + File.separator + time
        var file = File(basePath)
        var i = 1
@@ -163,7 +170,7 @@
            i++
        }
        if (file.exists()) {
            FileUtil().delAllFile(basePath)
            FileUtil.delAllFile(basePath)
        } else {
            file.mkdirs()
        }
@@ -180,7 +187,7 @@
                i++
            }
            if (sFile.exists()) {
                FileUtil().delAllFile(subTaskFilePath)
                FileUtil.delAllFile(subTaskFilePath)
            } else {
                sFile.mkdirs()
            }
@@ -196,7 +203,7 @@
                    i++
                }
                if (pFile.exists()) {
                    FileUtil().delAllFile(pPath)
                    FileUtil.delAllFile(pPath)
                } else {
                    pFile.mkdirs()
                }
@@ -209,7 +216,7 @@
                    val fromFile = File(picPath)
                    val picName = p.problemname + "_" + p.location + "($y).jpg"
                    val toFile = File(pPath + File.separator + picName)
                    FileUtil().copy(fromFile, toFile)
                    FileUtil.copy(fromFile, toFile)
                    y++
                }
            }
@@ -241,14 +248,10 @@
        return response
    }
    override fun downloadPic2(
        sceneType: Int,
        topTaskId: String,
        response: HttpServletResponse
    ): HttpServletResponse {
    override fun downloadPic2(sceneType: Int, topTaskId: String, response: HttpServletResponse): HttpServletResponse {
        //建立第一层目录,包含所有的任务
        val topTask = taskMapper.selectByPrimaryKey(topTaskId)
        val time = DateUtil().DateToString(Date(), "yyyy-MM-dd_HH-mm-ss")
        val time = dateUtil.DateToString(Date(), "yyyy-MM-dd_HH-mm-ss")
        val basePath = Constant.DEFAULT_FILE_PATH + File.separator + "images" + File.separator + "temp" + File.separator + topTask.name
        val file = File(basePath)
        if (!file.exists()) {
@@ -281,7 +284,7 @@
                    i++
                }
                if (sFile.exists()) {
                    FileUtil().delAllFile(subTaskFilePath)
                    FileUtil.delAllFile(subTaskFilePath)
                } else {
                    sFile.mkdirs()
                }
@@ -311,7 +314,7 @@
                            i++
                        }
                        if (pFile.exists()) {
                            FileUtil().delAllFile(pPath)
                            FileUtil.delAllFile(pPath)
                        } else {
                            pFile.mkdirs()
                        }
@@ -322,7 +325,7 @@
                            val fromFile = File(picPath)
                            val picName = f.description
                            val toFile = File(pPath + File.separator + picName)
                            FileUtil().copy(fromFile, toFile)
                            FileUtil.copy(fromFile, toFile)
                        }
                    }
                }
@@ -381,304 +384,6 @@
        return BaseResponse(true, head = DataHead(p.pageNum, p.pages), data = result)
    }
    private fun getTableTitles(): List<String> = listOf(
            "序号", "任务", "场景", "经度", "纬度",
            "类型",
            "开始时间", "结束时间",
            "状态", "组长",
            "组员", "问题类型","问题详情", "街镇", "审核"
    )
    /**
     * ç›¸æ¯”于getTableContents() ï¼Œåˆ å‡äº†éƒ¨åˆ†åˆ—
     */
    private fun getTableTitles2(): List<String> = listOf(
//            "序号",
            "任务",
//            "场景", "经度", "纬度",
            "类型",
            "开始时间",
//            "结束时间",
            "状态", "组长",
            "组员", "问题类型","问题详情", "街镇", "审核"
    )
    private fun getTableContents(config: ExcelConfigVo): List<Array<Any>> {
        val townName = if (config.townCode == null) {
            null
        } else {
            val l = townMapper.selectByExample(Example(Town::class.java).apply {
                createCriteria().andEqualTo("towncode", config.townCode)
            })
            if (l.isNotEmpty()) {
                l[0].townname
            } else {
                null
            }
        }
        val subTaskExample = Example(Subtask::class.java).apply {
            if (config.subTaskIdList != null && config.subTaskIdList.isNotEmpty()) {
                createCriteria().apply {
                    config.subTaskIdList.forEach {
                        orEqualTo("stguid", it)
                    }
                }
            } else {
                createCriteria()
                        .andEqualTo("tguid", config.topTaskGuid)
                        .andGreaterThanOrEqualTo("planstarttime", config.startTime)
                        .andLessThanOrEqualTo("planendtime", config.endTime).apply {
                            config.provinceCode?.let {
                                andEqualTo("provincecode", it)
                            }
                            config.cityCode?.let {
                                andEqualTo("citycode", it)
                            }
                            config.districtCode?.let {
                                andEqualTo("districtcode", it)
                            }
//                            config.townCode?.let {
//                                andEqualTo("towncode", it)
//                            }
                        }
            }
            orderBy("planstarttime")
        }
        val contents = mutableListOf<Array<Any>>()
        val subTasks = mutableListOf<Subtask>()
        var i = 1
        subtaskMapper.selectByExample(subTaskExample).forEach {
            //查询该任务对应的场景
            val scene = scenseMapper.selectByPrimaryKey(it.scenseid)
            //根据场景条件筛选
            val need = if (config.sceneType != null) {
                scene.typeid == config.sceneType.toByte()
            } else {
                true
            }
            if (need) {
                //记录查询到子任务
                subTasks.add(it)
                val problemTypes = mutableListOf<String>()
                val problems = mutableListOf<String>()
                val districts = mutableListOf<String>()
                val checkStatus= mutableListOf<String>()
                //查询子任务对应的问题,并且根据条件进行筛选
                val problemlistExample = Example(Problemlist::class.java).apply {
                    createCriteria().andEqualTo("stguid", it.stguid).apply {
                        config.problemName?.let {p->
                            andEqualTo("problemname", p)
                        }
                        townName?.let {t->
                            andLike("location", "%$t%")
                        }
                    }
                }
                var y=1
                problemlistMapper.selectByExample(problemlistExample).forEach problemType@{p->
                    val result = problemtypeMapper.selectByPrimaryKey(p.ptguid)
                    if (config.problemTypeName != null) {
                        if (result.typename != config.problemTypeName) {
                            return@problemType
                        }
                    }
                    problemTypes.add(result.typename ?: "")
                    problems.add("$y、${p.problemname}")
                    districts.add(p.location ?: "")
                    val status = when (p.extension3) {
                        Constant.PROBLEM_UNCHECKED -> "未审核"
                        Constant.PROBLEM_CHECK_PASS-> "通过"
                        Constant.PROBLEM_CHECK_FAIL -> "未通过"
                        else->"未审核"
                    }
                    checkStatus.add(status)
                    y++
                }
                //当有问题作为筛选条件时,如果没有找到对应问题,则该次任务去除
                if ( (config.problemTypeName != null || config.problemName != null || townName != null)
                        && (problemTypes.isEmpty() && problems.isEmpty())) {
                    return@forEach
                }
                val rowContent = arrayOf<Any>(
                        "$i", it.name ?: "", it.scensename ?: "", scene.longitude.toString(), scene.latitude.toString(),
                        scene.type ?: "",
                        DateUtil().DateToString(it.executionstarttime, "yyyy-MM-dd HH:mm:ss") ?: "", DateUtil().DateToString(it.executionendtime, "yyyy-MM-dd hh:mm:ss") ?: "",
                        it.status ?: "", it.assessorrealname?.replace("#", "、") ?: "",
                        it.executorrealtimes?.replace("#", "、") ?: "", problemTypes.toTypedArray(), problems.toTypedArray(), districts.toTypedArray(), checkStatus.toTypedArray()
                )
                contents.add(rowContent)
                i++
            }
        }
        return contents
    }
    /**
     * ç›¸æ¯”于getTableContents() ï¼Œåˆ å‡äº†éƒ¨åˆ†åˆ—
     */
    private fun getTableContents2(config: ExcelConfigVo): List<Array<Any>> {
        val townName = if (config.townCode == null) {
            null
        } else {
            val l = townMapper.selectByExample(Example(Town::class.java).apply {
                createCriteria().andEqualTo("towncode", config.townCode)
            })
            if (l.isNotEmpty()) {
                l[0].townname
            } else {
                null
            }
        }
        val subTaskExample = Example(Subtask::class.java).apply {
            if (config.subTaskIdList != null && config.subTaskIdList.isNotEmpty()) {
                createCriteria().apply {
                    config.subTaskIdList.forEach {
                        orEqualTo("stguid", it)
                    }
                }
            } else {
                createCriteria()
                        .andEqualTo("tguid", config.topTaskGuid)
                        .andGreaterThanOrEqualTo("planstarttime", config.startTime)
                        .andLessThanOrEqualTo("planendtime", config.endTime).apply {
                            config.provinceCode?.let {
                                andEqualTo("provincecode", it)
                            }
                            config.cityCode?.let {
                                andEqualTo("citycode", it)
                            }
                            config.districtCode?.let {
                                andEqualTo("districtcode", it)
                            }
//                            config.townCode?.let {
//                                andEqualTo("towncode", it)
//                            }
                        }
            }
            orderBy("planstarttime")
        }
        val contents = mutableListOf<Array<Any>>()
        val subTasks = mutableListOf<Subtask>()
        var i = 1
        subtaskMapper.selectByExample(subTaskExample).forEach {
            //查询该任务对应的场景
            val scene = scenseMapper.selectByPrimaryKey(it.scenseid)
            //根据场景条件筛选
            val need = if (config.sceneType != null) {
                scene.typeid == config.sceneType.toByte()
            } else {
                true
            }
            if (need) {
                //记录查询到子任务
                subTasks.add(it)
                val problemTypes = mutableListOf<String>()
                val problems = mutableListOf<String>()
                val districts = mutableListOf<String>()
                val checkStatus= mutableListOf<String>()
                //查询子任务对应的问题,并且根据条件进行筛选
                val problemlistExample = Example(Problemlist::class.java).apply {
                    createCriteria().andEqualTo("stguid", it.stguid).apply {
                        config.problemName?.let {p->
                            andEqualTo("problemname", p)
                        }
                        townName?.let {t->
                            andLike("location", "%$t%")
                        }
                    }
                }
                var y=1
                problemlistMapper.selectByExample(problemlistExample).forEach problemType@{p->
                    val result = problemtypeMapper.selectByPrimaryKey(p.ptguid)
                    if (config.problemTypeName != null) {
                        if (result?.typename != config.problemTypeName) {
                            return@problemType
                        }
                    }
                    problemTypes.add(result?.typename ?: "")
                    problems.add("$y、${p.problemname}")
                    districts.add(p.location ?: "")
                    val status = when (p.extension3) {
                        Constant.PROBLEM_UNCHECKED -> "未审核"
                        Constant.PROBLEM_CHECK_PASS-> "通过"
                        Constant.PROBLEM_CHECK_FAIL -> "未通过"
                        else->"未审核"
                    }
                    checkStatus.add(status)
                    y++
                }
                //当有问题作为筛选条件时,如果没有找到对应问题,则该次任务去除
                if ( (config.problemTypeName != null || config.problemName != null || townName != null)
                        && (problemTypes.isEmpty() && problems.isEmpty())) {
                    return@forEach
                }
//                val lineMaxSize =3
//
//                val leader = it.assessorrealname?.split("#")
//                val leaderStr = StringBuilder()
//                for (t in 0 until (leader?.size ?: 0)) {
//                    if (t > 0) {
//                        leaderStr.append("、")
//                    }
//                    if (t == lineMaxSize - 1) {
//                        leaderStr.append("\r\n")
//                    }
//                    leaderStr.append(leader?.get(t))
//                }
//
//                val member = it.executorrealtimes?.split("#")
//                val memberStr = StringBuilder()
//                for (t in 0 until (member?.size ?: 0)) {
//                    if (t > 0) {
//                        memberStr.append("、")
//                    }
//                    if (t == lineMaxSize - 1) {
//                        memberStr.append("\r\n")
//                    }
//                    memberStr.append(member?.get(t))
//                }
                val rowContent = arrayOf<Any>(
//                        "$i",
                        it.name ?: "",
//                        it.scensename ?: "", scene.longitude.toString(), scene.latitude.toString(),
                        scene.type ?: "",
                        DateUtil().DateToString(it.executionstarttime, "yyyy-MM-dd HH:mm:ss") ?: "",
//                        DateUtil().DateToString(it.executionendtime, "yyyy-MM-dd hh:mm:ss") ?: "",
                        it.status ?: "", it.assessorrealname?.replace("#", "、") ?: "",
                        it.executorrealtimes?.replace("#", "、") ?: "", problemTypes.toTypedArray(), problems.toTypedArray(), districts.toTypedArray(), checkStatus.toTypedArray()
                )
                contents.add(rowContent)
                i++
            }
        }
        return contents
    }
    override fun searchSubTaskByKeyword(userId: String, keyword: String, page: Int, perPage: Int): BaseResponse<List<SubtaskVo>> {
        val userInfo = userinfoMapper.selectByPrimaryKey(userId)
        if (userInfo.usertypeid?.toInt() == 3) return BaseResponse(false, "企业用户无查询权限")//企业用户无法查询
@@ -688,7 +393,8 @@
            createCriteria().andLike("name", "%${keyword}%")
                .apply {
                    when (userInfo.usertypeid?.toInt()) {
                        0 -> {} //管理员用户查询无其他限制
                        0 -> {
                        } //管理员用户查询无其他限制
                        1 -> andLike("executorguids", "%${userId}%")//对于一般的巡查人员,只能查询到自己参与的子任务
                        2 -> andEqualTo("districtcode", userInfo.dGuid)//此处对于政府用户,dGuid存储的是区县编号
                    }
@@ -700,6 +406,504 @@
            result.add(vo)
        }
        return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages) ,data = result)
        return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result)
    }
    private fun getTable(mode: Int, config: ExcelConfigVo): Pair<MutableList<Array<Any>>, MutableList<Array<Any>>> {
        //数据源
        val dataList = getTableDataSource(config)
        //生成表格
        val head = mutableListOf<MutableList<Any>>()
        val contents = mutableListOf<MutableList<Any>>()
        getSceneName(head, contents, dataList)
        when (mode) {
            // é—®é¢˜åˆ†å¸ƒ
            1 -> {
                getProblemDistribution(head, contents, dataList, config)
            }
            2 -> {
                getInspectionInfo(head, contents, dataList, config)
            }
            3 -> {
            }
        }
        val h = mutableListOf<Array<Any>>()
        val c = mutableListOf<Array<Any>>()
        head.forEach { h.add(it.toTypedArray()) }
        contents.forEach { c.add(it.toTypedArray()) }
        c.sortBy {
            it[0] as Int
        }
        return Pair(h, c)
    }
    // è¡¨å¤´ï¼šåœºæ™¯å
    private fun getSceneName(head: MutableList<MutableList<Any>>, contents: MutableList<MutableList<Any>>, dataList: List<Subtask>) {
        head.add(mutableListOf(ExcelUtil.MyCell("表单编号"), ExcelUtil.MyCell("唯一序号"), ExcelUtil.MyCell("场景名称")))
        dataList.forEach {subtask ->
            val row = mutableListOf<Any>()
            //查询该任务对应的场景
            val scene = scenseMapper.selectByPrimaryKey(subtask.scenseid)
            row.apply {
                add(scene.index ?: -99)
                add(scene.extension2 ?: "")
                add(scene.name ?: "")
            }
            contents.add(row)
        }
    }
    // è¡¨å¤´ï¼šå…·ä½“问题分布
    private fun getProblemDistribution(head: MutableList<MutableList<Any>>, contents: MutableList<MutableList<Any>>,
                                       dataList: List<Subtask>, config: ExcelConfigVo) {
        val h1 = mutableListOf<ExcelUtil.MyCell>()
        val h2 = mutableListOf<Any>()
        currentProblemType.clear()
        currentProblemHead.clear()
        // é—®é¢˜åˆ†ä¸ºä¸¤å±‚,新增一行表头
        problemtypeMapper.selectByExample(Example(Problemtype::class.java).apply {
            createCriteria().andEqualTo("scensetypeid", config.sceneType)
                .andEqualTo("districtcode", config.districtCode)
            orderBy("extension1")
        }).forEach {
            if (!currentProblemHead.contains(it.typename)) {
                currentProblemHead.add(it.typename ?: "")
                h1.add(ExcelUtil.MyCell(it.typename ?: "", colSpan = 0))
            }
            currentProblemType[it.guid ?: ""] = it.description ?: ""
            if (currentProblemHead.contains(it.typename)) {
                h2.add(it.description ?: "")
                h1.last().colSpan++
                h2.add("是否整改")
                h1.last().colSpan++
            }
        }
        //问题分布
        for (i in dataList.indices) {
            val subtask = dataList[i]
            val pDis = mutableListOf<Any>()//具体问题分布及整改情况
            repeat(h2.size) { pDis.add("")}
            if (subtask.stguid != null) {
                problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                    createCriteria().andEqualTo("stguid", subtask.stguid)
                }).forEach problemType@{ p ->
                    val des = currentProblemType[p.ptguid]
                    //具体问题分布
                    for (t in h2.indices) {
                        if (des == h2[t]) {
                            //具体问题这一列添加文本,表示问题存在
                            pDis[t] = 1
                            //问题列的下一列是该问题的整改情况
                            pDis[t + 1] = if (p.ischanged == true) 1 else 0
                            break
                        }
                    }
                }
            }
            contents[i].addAll(pDis)
        }
        //原有的第一行表头增加1行行跨度,同时新的第二行表头添加空位
        head[0].forEach {
            (it as ExcelUtil.MyCell).rowSpan++
            h2.add(0, "")
        }
        //合并表头
        head[0].addAll(h1)
        head.add(h2)
    }
    // è¡¨å¤´ï¼šå·¡æŸ¥æƒ…况及问题、整改统计
    private fun getInspectionInfo(head: MutableList<MutableList<Any>>, contents: MutableList<MutableList<Any>>, dataList: List<Subtask>, config: ExcelConfigVo) {
        val h1 = listOf("监管时间", "问题类型", "问题描述", "问题位置", "问题数", "整改情况", "整改问题", "整改数", "未整改问题", "未整改数", "审核情况")
        for (i in dataList.indices) {
            val subtask = dataList[i]
            val row = mutableListOf<Any>()
            if (subtask.stguid == null) {
                repeat(h1.size) { row.add("")}
            } else {
                row.apply {
                    // è¡¨å¤´ï¼šå·¡æŸ¥æƒ…况及问题、整改统计
                    add(dateUtil.DateToString(subtask.planstarttime, DateUtil.DateStyle.MM_DD) ?: "")//监管时间
                    //查询子任务对应的问题,并且根据条件进行筛选
                    var y = 1
                    var pType = ""//问题类型
                    var pDes = ""//问题描述
                    var pLoc = ""//问题位置
                    var pNum = 0//问题数
                    var pChanged = ""//整改情况
                    var changedProblem = ""//整改问题
                    var cNum = 0//整改数
                    var unChangedProblem = ""//未整改问题
                    var unChangeNum = 0//未整改数
                    var checkStatus = ""//审核情况
                    problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                        createCriteria().andEqualTo("stguid", subtask.stguid)
                    }).forEach problemType@{ p ->
                        val problemType = problemtypeMapper.selectByPrimaryKey(p.ptguid)
                        val typeName = if (problemType == null) {
                            val a = ""
                            a
                        } else {
                            problemType.typename
                        }
                        val lr = if (y > 1) "\n" else ""
                        //巡查情况及问题、整改统计
                        pType += "${lr}$y、${typeName}"
                        pDes += "${lr}$y、${p.problemname}"
                        pLoc += "${lr}$y、${p.location}"
                        pNum++
                        pChanged += "${lr}$y、${if (p.ischanged == true) "✓" else "×"}"
                        if (p.ischanged == true) {
                            if (changedProblem.isNotBlank()) {
                                changedProblem += "\n"
                            }
                            changedProblem += "$y、${p.problemname}"
                            cNum++
                        } else {
                            if (unChangedProblem.isNotBlank()) {
                                unChangedProblem += "\n"
                            }
                            unChangedProblem += "$y、${p.problemname}"
                            unChangeNum++
                        }
                        val status = when (p.extension3) {
                            Constant.PROBLEM_CHECK_PASS -> "问题审核通过"//
                            Constant.PROBLEM_CHECK_FAIL -> "问题审核未通过"//
                            Constant.PROBLEM_UNCHECKED -> "问题未审核"//
                            Constant.CHANGE_UNCHECKED -> "整改未审核"//
                            Constant.CHANGE_CHECK_PASS -> "整改审核通过"//
                            Constant.CHANGE_CHECK_FAIL -> "整改审核未通过"//
                            else -> "问题未审核"
                        }
                        checkStatus += "${lr}$y、${status}"
                        y++
                    }
                    addAll(listOf(pType, pDes, pLoc, pNum, pChanged, changedProblem, cNum, unChangedProblem, unChangeNum, checkStatus))
                }
            }
            contents[i].addAll(row)
        }
        head[0].addAll(h1)
    }
    private fun getTableTitles(sceneType: Int?, districtCode: String?): List<String> {
        if (sceneType == null || districtCode == null) return emptyList()
        val heads = mutableListOf<String>()
        heads.run {
            addAll(getSceneName())
            addAll(getLocation())
            addAll(getBaseInfo(sceneType))
            addAll(getContactInfo(sceneType))
            addAll(getRealTimeStatus(sceneType))
            addAll(getInspectionInfo(sceneType))
            addAll(getProblemDistribution(sceneType, districtCode))
        }
        return heads
    }
    // è¡¨å¤´ï¼šåœºæ™¯å
    private fun getSceneName() = listOf("表单编号", "唯一序号", "场景名称")
    // è¡¨å¤´ï¼šåœºæ™¯åœ°ç†ä½ç½®
    private fun getLocation(): List<String> = listOf(
        "街镇", "地址"
    )
    // è¡¨å¤´ï¼šåœºæ™¯ä¸“属基础信息
    private fun getBaseInfo(sceneType: Int): List<String> = when (sceneType.toString()) {
        Constant.ScenseType.TYPE1.value -> listOf("业主单位", "施工单位", "建筑面积(m²)", "施工起始时间", "施工结束时间", "施工阶段", "工程类型")
        Constant.ScenseType.TYPE2.value -> listOf("业主单位", "租赁单位", "占地面积(m²)", "营运状态", "类型")
        Constant.ScenseType.TYPE3.value -> listOf("业主单位", "文明场站", "绿色环保站厂", "占地面积(m²)", "营运状态")
        Constant.ScenseType.TYPE14.value -> listOf("业主单位", "租赁单位", "占地面积(m²)", "营运状态", "类型")
        else -> listOf()
    }
    // è¡¨å¤´ï¼šåœºæ™¯è”系方式
    private fun getContactInfo(sceneType: Int): List<String> = when (sceneType) {
        else -> listOf("联系人", "联系方式")
    }
    // è¡¨å¤´ï¼šåœºæ™¯çŽ°åœºæƒ…å†µ
    private fun getRealTimeStatus(sceneType: Int): List<String> = when (sceneType) {
        else -> listOf()
    }
    // è¡¨å¤´ï¼šå·¡æŸ¥æƒ…况及问题、整改统计
    private fun getInspectionInfo(sceneType: Int): List<String> = when (sceneType) {
        else -> listOf("监管时间", "防治考核评分", "防治规范性", "扣分项","问题类型", "问题描述", "问题位置", "问题数", "整改情况", "整改数", "审核情况")
    }
    // è¡¨å¤´ï¼šå…·ä½“问题分布
    private val currentProblemType = mutableMapOf<String, String>()
    private val currentProblemHead = mutableListOf<String>()
    private fun getProblemDistribution(sceneType: Int, districtCode: String): List<String> {
        val heads = mutableListOf<String>()
        currentProblemType.clear()
        currentProblemHead.clear()
        problemtypeMapper.selectByExample(Example(Problemtype::class.java).apply {
            createCriteria().andEqualTo("scensetypeid", sceneType)
                .andEqualTo("districtcode", districtCode)
            orderBy("typeid")
        }).forEach {
            if (!heads.contains(it.typename)) {
                heads.add(it.typename ?: "")
            }
            currentProblemType[it.guid ?: ""] = it.typename ?: ""
        }
        currentProblemHead.addAll(heads)
        return heads
    }
    /**
     * èŽ·å–è¡¨æ ¼æ•°æ®æº
     */
    private fun getTableDataSource(config: ExcelConfigVo): List<Subtask> {
        if (config.sceneType == null) return emptyList()
        val result = mutableListOf<Subtask>()
        //1. æŸ¥æ‰¾ç‰¹å®šçš„巡查任务或者所有的计划巡查任务
        var taskSceneIdList = listOf<String>()
        val subTaskList = if (config.subTaskIdList?.isNotEmpty() == true ||
            (config.startTime != null || config.endTime != null)
        ) {
            subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().apply {
                    if (config.subTaskIdList?.isNotEmpty() == true) {
                        andIn("stguid", config.subTaskIdList)
                    }
                    config.startTime?.let { andGreaterThanOrEqualTo("planstarttime", it) }
                    config.endTime?.let { andLessThanOrEqualTo("planendtime", it) }
                }
            })
        } else {
            taskSceneIdList = monitorobjectversionMapper.getSceneByType(config.topTaskGuid, config.sceneType)
            subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().andIn("scenseid", taskSceneIdList)
                    .andEqualTo("tguid", config.topTaskGuid)
            })
        }
        if (taskSceneIdList.isNotEmpty()) {
            taskSceneIdList.forEach {
                var subtask: Subtask? = null
                for (s in subTaskList) {
                    if (s.scenseid == it) {
                        subtask = s
                        break
                    }
                }
                if (subtask == null) subtask = Subtask().apply { scenseid = it }
                result.add(subtask)
            }
        } else {
            result.addAll(subTaskList)
        }
        return result
    }
    private fun getTableContents(config: ExcelConfigVo, colCounts: Int = 0): List<Array<Any>> {
        if (config.sceneType == null) return emptyList()
        //1. æŸ¥æ‰¾ç‰¹å®šçš„巡查任务或者所有的计划巡查任务
        var taskSceneIdList = listOf<String>()
        val subTaskList = if (config.subTaskIdList?.isNotEmpty() == true ||
            (config.startTime != null || config.endTime != null)
        ) {
            subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().apply {
                    if (config.subTaskIdList?.isNotEmpty() == true) {
                        andIn("stguid", config.subTaskIdList)
                    }
                    config.startTime?.let { andGreaterThanOrEqualTo("planstarttime", it) }
                    config.endTime?.let { andLessThanOrEqualTo("planendtime", it) }
                }
            })
        } else {
            taskSceneIdList = monitorobjectversionMapper.getSceneByType(config.topTaskGuid, config.sceneType)
            subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().andIn("scenseid", taskSceneIdList)
                    .andEqualTo("tguid", config.topTaskGuid)
            })
        }
        val contents = mutableListOf<Array<Any>>()
        val subTasks = mutableListOf<Subtask>()
        if (taskSceneIdList.isNotEmpty()) {
            taskSceneIdList.forEach {
                val rowContent = mutableListOf<Any>()
                var subtask: Subtask? = null
                for (s in subTaskList) {
                    if (s.scenseid == it) {
                        subtask = s
                        break
                    }
                }
                //该场景未巡查
                if (subtask == null) {
                    val scene = scenseMapper.selectByPrimaryKey(it)
                    rowContent.apply {
                        add(scene.index?.toString() ?: "")
                        add(scene.extension2 ?: "")
                        add(scene.name ?: "")
                    }
                    val left = colCounts - getSceneName().size
                    repeat(left) {
                        rowContent.add("")
                    }
                } else {
                    rowContent.addAll(tableContent(subtask))
                }
                contents.add(rowContent.toTypedArray())
            }
        } else {
            subTaskList.forEach {
                val c = tableContent(it)
                contents.add(c)
            }
        }
        return contents
    }
    private fun tableContent(subtask: Subtask): Array<Any> {
        val row = mutableListOf<Any>()
        //查询该任务对应的场景
        val scene = scenseMapper.selectByPrimaryKey(subtask.scenseid)
        row.apply {
            // è¡¨å¤´ï¼šåœºæ™¯å
            add(scene.index?.toString() ?: "")
            add(scene.extension2 ?: "")
            add(scene.name ?: "")
            // è¡¨å¤´ï¼šåœºæ™¯åœ°ç†ä½ç½®
            add(scene.townname ?: "")
            add(scene.location ?: "")
            // è¡¨å¤´ï¼šåœºæ™¯ä¸“属基础信息
            addAll(when (scene.typeid.toString()) {
                Constant.ScenseType.TYPE1.value -> {
//                    listOf("业主单位", "施工单位", "建筑面积(m²)", "施工起始时间", "施工结束时间", "施工阶段", "工程类型")
                    var r = listOf("-", "-", "-", "-", "-", "-", "-")
                    sceneConstructionSiteMapper.selectByPrimaryKey(scene.guid)?.let {
                        r = listOf(it.csEmployerUnit?:"", it.csConstructionUnit?:"", it.csFloorSpace?:"",
                            it.csStartTime?:"", it.csEndTime?:"", it.csStatus?:"", it.csProjectType?:"")
                    }
                    r
                }
                Constant.ScenseType.TYPE2.value -> {
//                    listOf("业主单位", "租赁单位", "占地面积(m²)", "营运状态", "类型")
                    var r = listOf("-", "-", "-", "-", "-")
                    sceneWharfMapper.selectByPrimaryKey(scene.guid)?.let {
                        r = listOf(it.getwEmployerUnit()?:"", it.getwRentUnit()?:"", it.getwFloorSpace()?:"", it.getwStatus()?:"",
                            it.getwProjectType()?:"")
                    }
                    r
                }
                Constant.ScenseType.TYPE3.value -> {
//                    listOf("业主单位", "文明场站", "绿色环保站厂", "占地面积(m²)", "营运状态")
                    var r = listOf("-", "-", "-", "-", "-")
                    sceneMixingPlantMapper.selectByPrimaryKey(scene.guid)?.let {
                        r = listOf(
                            it.mpEmployerUnit?:"", if (it.mpCivillyPlant == true) "是" else "否", if (it.mpGreenPlant == true) "是" else "否",
                            it.mpFloorSpace?:"", it.mpStatus?:""
                        )
                    }
                    r
                }
                Constant.ScenseType.TYPE14.value -> {
//                    listOf("业主单位", "租赁单位", "占地面积(m²)", "营运状态", "类型")
                    var r = listOf("-", "-", "-", "-", "-")
                    sceneStorageYardMapper.selectByPrimaryKey(scene.guid)?.let {
                        r = listOf(it.syEmployerUnit?:"", it.syRentUnit?:"", it.syFloorSpace?:"", it.syStatus?:"", it.syProjectType?:"")
                    }
                    r
                }
                else -> listOf()
            })
            // è¡¨å¤´ï¼šåœºæ™¯è”系方式
            add(scene.contacts ?: "")
            add(scene.contactst ?: "")
            // è¡¨å¤´ï¼šåœºæ™¯çŽ°åœºæƒ…å†µ
            // TODO: 2022/7/10 æš‚æ— 
            // è¡¨å¤´ï¼šå·¡æŸ¥æƒ…况及问题、整改统计 å’Œ è¡¨å¤´ï¼šå…·ä½“问题分布
            listOf("监管时间", "防治考核评分", "防治规范性", "扣分项","问题类型", "问题描述", "问题位置", "问题数", "整改情况", "整改数", "审核情况")
            add(dateUtil.DateToString(subtask.planstarttime, DateUtil.DateStyle.MM_DD) ?: "")
            add("")
            add("")
            add("")
            //查询子任务对应的问题,并且根据条件进行筛选
            var y = 1
            var pType = ""//问题类型
            var pDes = ""//问题描述
            var pLoc = ""//问题位置
            var pNum = 0//问题数
            var pChanged = ""//整改情况
            var cNum = 0//整改数
            var checkStatus = ""//审核情况
            var pDis = mutableListOf<String>()//具体问题分布
            repeat(currentProblemHead.size) { pDis.add("")}
            problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                createCriteria().andEqualTo("stguid", subtask.stguid)
            }).forEach problemType@{ p ->
                val typeName = currentProblemType[p.ptguid]
                val lr = if (y > 1) "\n" else ""
                //巡查情况及问题、整改统计
                pType += "${lr}$y、${typeName}"
                pDes += "${lr}$y、${p.problemname}"
                pLoc += "${lr}$y、${p.location}"
                pNum++
                pChanged += "${lr}$y、${if (p.ischanged == true) "✓" else "×"}"
                if (p.ischanged == true) cNum++
                val status = when (p.extension3) {
                    Constant.PROBLEM_CHECK_PASS -> "问题审核通过"//
                    Constant.PROBLEM_CHECK_FAIL -> "问题审核未通过"//
                    Constant.PROBLEM_UNCHECKED -> "问题未审核"//
                    Constant.CHANGE_UNCHECKED -> "整改未审核"//
                    Constant.CHANGE_CHECK_PASS -> "整改审核通过"//
                    Constant.CHANGE_CHECK_FAIL -> "整改审核未通过"//
                    else -> "问题未审核"
                }
                checkStatus += "${lr}$y、${status}"
                y++
                //具体问题分布
                for (t in currentProblemHead.indices) {
                    if (typeName == currentProblemHead[t]) {
                        pDis[t] = if (p.ischanged == true) "1" else "0"
                        break
                    }
                }
            }
            addAll(listOf(pType, pDes, pLoc, pNum, pChanged, cNum, checkStatus))
            addAll(pDis)
        }
        return row.toTypedArray()
    }
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/service/impl/VersionServiceImpl.kt
@@ -36,7 +36,7 @@
            val path = "crash/"
            try {
                //调用文件保存方法
                FileUtil().uploadFile(file.bytes, basePath + path, fileName!!)
                FileUtil.uploadFile(file.bytes, basePath + path, fileName!!)
                return true
            } catch (e: Exception) {
                e.printStackTrace()
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ExcelConfigVo.kt
@@ -9,14 +9,19 @@
 */
data class ExcelConfigVo(
        val topTaskGuid: String,
        val startTime: Date,
        val endTime: Date,
        val provinceCode: String?,
        val cityCode: String?,
        val districtCode: String?,
        val townCode: String?,
        val sceneType: Int?,
        val subTaskIdList: List<String>?,
        val problemTypeName: String?,
        val problemName: String?
        val startTime: Date? = null,
        val endTime: Date? = null,
        val provinceCode: String? = null,
        val cityCode: String? = null,
        val districtCode: String? = null,
        val townCode: String? = null,
        val sceneType: Int? = null,
        val subTaskIdList: List<String>? = null,
        val problemTypeName: String? = null,
        val problemName: String? = null
)
src/main/kotlin/cn/flightfeather/supervision/lightshare/vo/ProblemChangeVo.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package cn.flightfeather.supervision.lightshare.vo
import com.fasterxml.jackson.annotation.JsonInclude
import java.math.BigDecimal
@JsonInclude(JsonInclude.Include.NON_NULL)
class ProblemChangeVo {
    // é—®é¢˜id
    var proGuid: String? = null
    // æ•´æ”¹æ–¹å¼
    var changeCatalog: String? = null
}
src/main/kotlin/cn/flightfeather/supervision/lightshare/web/ProblemlistController.kt
@@ -53,7 +53,8 @@
    fun getChargeResult(@RequestBody areaVo: AreaVo): ChargeInfoVo = problemlistService.getChargeResult(areaVo)
    @GetMapping("/getProblemsByScene")
    fun getProblemsByScene(@RequestParam(value = "sceneId", required = true) sceneId: String, @RequestParam date: String): List<ProblemlistVo> = problemlistService.getProblemByScene(sceneId, date)
    fun getProblemsByScene(@RequestParam(value = "sceneId", required = true) sceneId: String, @RequestParam date: String): List<ProblemlistVo>
    = problemlistService.getProblemByScene(sceneId, date)
    @GetMapping("/month_anlysis")
    fun getMonthProblemsById(@RequestParam(value = "taskId", required = true) taskId: String,
@@ -75,4 +76,11 @@
        @RequestParam("problemVo") problemVo: String,
        @RequestPart("images") files: Array<MultipartFile>
    ) = problemlistService.newProblem(problemVo, files)
    @ApiOperation(value = "整改一个问题", notes = "简化上传所需问题信息,将大部分操作交由后台完成")
    @PostMapping("/changeProblem")
    fun changeProblem(
        @RequestParam("problemId") problemId: String,
        @RequestPart("images") files: Array<MultipartFile>
    ) = problemlistService.changeProblem(problemId, files)
}
src/main/resources/application.yml
@@ -14,14 +14,14 @@
  #    password: cn.FLIGHTFEATHER
      #-远程测试服务器-
#      url: jdbc:mysql://47.100.191.150:3306/supervision?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#      username: remoteU1
#      password: eSoF8DnzfGTlhAjE
      url: jdbc:mysql://47.100.191.150:3306/supervision?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
      username: remoteU1
      password: eSoF8DnzfGTlhAjE
      #-发布服务器-
      url: jdbc:mysql://localhost:3306/supervision?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
      username: supervision
      password: supervision_feiyu2021
#      url: jdbc:mysql://localhost:3306/supervision?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#      username: supervision
#      password: supervision_feiyu2021
      #-环境督察测试服务器-
  #    url: jdbc:mysql://192.168.0.200:3306/supervision_ii?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
@@ -56,14 +56,14 @@
      #-TestEnd-
      #-发布服务器-
      url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
      username: ledger
      password: ledger_fxxchackxr
#      url: jdbc:mysql://localhost:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#      username: ledger
#      password: ledger_fxxchackxr
      #   å¼€å‘远程服务器
#      url: jdbc:mysql://47.100.191.150:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#      username: remoteU1
#      password: eSoF8DnzfGTlhAjE
      url: jdbc:mysql://47.100.191.150:3306/ledger?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
      username: remoteU1
      password: eSoF8DnzfGTlhAjE
      initialSize: 5
      minIdle: 5
src/main/resources/mapper/ds1/SubtaskMapper.xml
@@ -5,53 +5,53 @@
    <!--
      WARNING - @mbg.generated
    -->
    <id column="ST_GUID" property="stGuid" jdbcType="VARCHAR" />
    <result column="T_GUID" property="tGuid" jdbcType="VARCHAR" />
    <result column="TS_GUID" property="tsGuid" jdbcType="VARCHAR" />
    <result column="ST_name" property="stName" jdbcType="VARCHAR" />
    <result column="ST_Priority" property="stPriority" jdbcType="BIT" />
    <result column="ST_TypeNo" property="stTypeno" jdbcType="TINYINT" />
    <result column="ST_Type" property="stType" jdbcType="VARCHAR" />
    <result column="ST_ProvinceCode" property="stProvincecode" jdbcType="VARCHAR" />
    <result column="ST_ProvinceName" property="stProvincename" jdbcType="VARCHAR" />
    <result column="ST_CityCode" property="stCitycode" jdbcType="VARCHAR" />
    <result column="ST_CityName" property="stCityname" jdbcType="VARCHAR" />
    <result column="ST_DistrictCode" property="stDistrictcode" jdbcType="VARCHAR" />
    <result column="ST_DistrictName" property="stDistrictname" jdbcType="VARCHAR" />
    <result column="ST_TownCode" property="stTowncode" jdbcType="VARCHAR" />
    <result column="ST_TownName" property="stTownname" jdbcType="VARCHAR" />
    <result column="ST_ScenseName" property="stScensename" jdbcType="VARCHAR" />
    <result column="ST_ScenseID" property="stScenseid" jdbcType="VARCHAR" />
    <result column="ST_ScenseAddress" property="stScenseaddress" jdbcType="VARCHAR" />
    <result column="ST_DeadLineType" property="stDeadlinetype" jdbcType="VARCHAR" />
    <result column="ST_PlanStartTime" property="stPlanstarttime" jdbcType="TIMESTAMP" />
    <result column="ST_PlanEndTime" property="stPlanendtime" jdbcType="TIMESTAMP" />
    <result column="ST_DeployerGUID" property="stDeployerguid" jdbcType="VARCHAR" />
    <result column="ST_DeployerUserName" property="stDeployerusername" jdbcType="VARCHAR" />
    <result column="ST_DeployerRealName" property="stDeployerrealname" jdbcType="VARCHAR" />
    <result column="ST_DeployTime" property="stDeploytime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutionStartTime" property="stExecutionstarttime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutionEndTime" property="stExecutionendtime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutorGUIDs" property="stExecutorguids" jdbcType="VARCHAR" />
    <result column="ST_ExecutorUserNames" property="stExecutorusernames" jdbcType="VARCHAR" />
    <result column="ST_ExecutorRealTimes" property="stExecutorrealtimes" jdbcType="VARCHAR" />
    <result column="ST_Status" property="stStatus" jdbcType="VARCHAR" />
    <result column="ST_NotifedCount" property="stNotifedcount" jdbcType="INTEGER" />
    <result column="ST_RuleList" property="stRulelist" jdbcType="VARCHAR" />
    <id column="ST_GUID" property="stguid" jdbcType="VARCHAR" />
    <result column="T_GUID" property="tguid" jdbcType="VARCHAR" />
    <result column="TS_GUID" property="tsguid" jdbcType="VARCHAR" />
    <result column="ST_name" property="name" jdbcType="VARCHAR" />
    <result column="ST_Priority" property="priority" jdbcType="BIT" />
    <result column="ST_TypeNo" property="typeno" jdbcType="TINYINT" />
    <result column="ST_Type" property="type" jdbcType="VARCHAR" />
    <result column="ST_ProvinceCode" property="provincecode" jdbcType="VARCHAR" />
    <result column="ST_ProvinceName" property="provincename" jdbcType="VARCHAR" />
    <result column="ST_CityCode" property="citycode" jdbcType="VARCHAR" />
    <result column="ST_CityName" property="cityname" jdbcType="VARCHAR" />
    <result column="ST_DistrictCode" property="districtcode" jdbcType="VARCHAR" />
    <result column="ST_DistrictName" property="districtname" jdbcType="VARCHAR" />
    <result column="ST_TownCode" property="towncode" jdbcType="VARCHAR" />
    <result column="ST_TownName" property="townname" jdbcType="VARCHAR" />
    <result column="ST_ScenseName" property="scensename" jdbcType="VARCHAR" />
    <result column="ST_ScenseID" property="scenseid" jdbcType="VARCHAR" />
    <result column="ST_ScenseAddress" property="scenseaddress" jdbcType="VARCHAR" />
    <result column="ST_DeadLineType" property="deadlinetype" jdbcType="VARCHAR" />
    <result column="ST_PlanStartTime" property="planstarttime" jdbcType="TIMESTAMP" />
    <result column="ST_PlanEndTime" property="planendtime" jdbcType="TIMESTAMP" />
    <result column="ST_DeployerGUID" property="deployerguid" jdbcType="VARCHAR" />
    <result column="ST_DeployerUserName" property="deployerusername" jdbcType="VARCHAR" />
    <result column="ST_DeployerRealName" property="deployerrealname" jdbcType="VARCHAR" />
    <result column="ST_DeployTime" property="deploytime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutionStartTime" property="executionstarttime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutionEndTime" property="executionendtime" jdbcType="TIMESTAMP" />
    <result column="ST_ExecutorGUIDs" property="executorguids" jdbcType="VARCHAR" />
    <result column="ST_ExecutorUserNames" property="executorusernames" jdbcType="VARCHAR" />
    <result column="ST_ExecutorRealTimes" property="executorrealtimes" jdbcType="VARCHAR" />
    <result column="ST_Status" property="status" jdbcType="VARCHAR" />
    <result column="ST_NotifedCount" property="notifedcount" jdbcType="INTEGER" />
    <result column="ST_RuleList" property="rulelist" jdbcType="VARCHAR" />
    <result column="ST_AssessorGUID" property="stAssessorguid" jdbcType="VARCHAR" />
    <result column="ST_AssessorUserName" property="stAssessorusername" jdbcType="VARCHAR" />
    <result column="ST_AssessorRealName" property="stAssessorrealname" jdbcType="VARCHAR" />
    <result column="ST_AssessTime" property="stAssesstime" jdbcType="TIMESTAMP" />
    <result column="ST_AssessResult" property="stAssessresult" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorGUID" property="stThirdassessorguid" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorUserName" property="stThirdassessorusername" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorRealName" property="stThirdassessorrealname" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessTime" property="stThirdassesstime" jdbcType="TIMESTAMP" />
    <result column="ST_ThirdAssessResult" property="stThirdassessresult" jdbcType="VARCHAR" />
    <result column="ST_Extension1" property="stExtension1" jdbcType="VARCHAR" />
    <result column="ST_Extension2" property="stExtension2" jdbcType="VARCHAR" />
    <result column="ST_Extension3" property="stExtension3" jdbcType="VARCHAR" />
    <result column="ST_Remark" property="stRemark" jdbcType="VARCHAR" />
    <result column="ST_AssessorUserName" property="assessorusername" jdbcType="VARCHAR" />
    <result column="ST_AssessorRealName" property="assessorrealname" jdbcType="VARCHAR" />
    <result column="ST_AssessTime" property="assesstime" jdbcType="TIMESTAMP" />
    <result column="ST_AssessResult" property="assessresult" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorGUID" property="thirdassessorguid" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorUserName" property="thirdassessorusername" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessorRealName" property="thirdassessorrealname" jdbcType="VARCHAR" />
    <result column="ST_ThirdAssessTime" property="thirdassesstime" jdbcType="TIMESTAMP" />
    <result column="ST_ThirdAssessResult" property="thirdassessresult" jdbcType="VARCHAR" />
    <result column="ST_Extension1" property="extension1" jdbcType="VARCHAR" />
    <result column="ST_Extension2" property="extension2" jdbcType="VARCHAR" />
    <result column="ST_Extension3" property="extension3" jdbcType="VARCHAR" />
    <result column="ST_Remark" property="remark" jdbcType="VARCHAR" />
  </resultMap>
  
  <resultMap id="SubtaskSearchResultVo" type="cn.flightfeather.supervision.lightshare.vo.SubtaskSearchResultVo">
@@ -251,4 +251,12 @@
            and b.S_TypeID = #{param4}
        </if>
    </select>
    <select id="selectByTopTask2" resultMap="BaseResultMap">
        select * from tm_t_subtask as a left join sm_t_scense as b on a.ST_ScenseID = b.S_GUID
        where a.T_GUID = #{param1}
        <if test="param2 != null">
            and b.S_TypeID = #{param2}
        </if>
    </select>
</mapper>
src/test/kotlin/cn/flightfeather/supervision/business/fume/AutoScoreTest.kt
@@ -1,7 +1,9 @@
package cn.flightfeather.supervision.business.fume
import cn.flightfeather.supervision.business.storage.StAutoScore
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.domain.ds1.mapper.ProblemlistMapper
import cn.flightfeather.supervision.domain.ds1.mapper.SubtaskMapper
import cn.flightfeather.supervision.domain.ds1.mapper.UserinfoMapper
import cn.flightfeather.supervision.domain.ds2.mapper.LedgerSubTypeMapper
import org.junit.Test
@@ -31,11 +33,18 @@
    @Autowired
    lateinit var problemlistMapper: ProblemlistMapper
    @Autowired
    lateinit var subtaskMapper: SubtaskMapper
    @Test
    fun go() {
//        autoScore.go(2022, 3)
        autoScore3.go(2022, 1, 2)
        autoScore.sceneType = Constant.ScenseType.TYPE1
        autoScore.topTaskGrade("Z3RwJ5jF123sjDsj")
//        autoScore3.go(2022, 1, 2)
//        val t = problemlistMapper.getStatisticalResult("310116", "2021-09-01 00:00:00", "2021-09-30 00:00:00", "1")
//        println()
//        val a = "01"
//        println(a.toInt())
    }
}
src/test/kotlin/cn/flightfeather/supervision/lightshare/service/impl/SearchServiceImplTest.kt
@@ -4,17 +4,21 @@
import cn.flightfeather.supervision.lightshare.service.SearchService
import cn.flightfeather.supervision.lightshare.vo.ExcelConfigVo
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import org.springframework.test.context.junit4.SpringRunner
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest(classes = [SupervisionApplication::class])
@RunWith(SpringRunner::class)
@ExtendWith(SpringExtension::class)
@SpringBootTest
class SearchServiceImplTest {
    @Autowired
@@ -26,9 +30,6 @@
        val localTimeE = LocalDateTime.of(2021, 3, 31, 23, 59, 59)
        val sD = Date.from(localTimeS.atZone(ZoneId.systemDefault()).toInstant())
        val eD = Date.from(localTimeE.atZone(ZoneId.systemDefault()).toInstant())
        searchService.writeToFile(ExcelConfigVo(
                "EPnTo3hoOWZXAU33",
                sD, eD, "31", "3100", "310104", null, 5, null, null, null
        ))
        searchService.writeToFile(ExcelConfigVo("Z3RwJ5jF123sjDsj", districtCode = "310106", sceneType = 1))
    }
}