feiyu02
2022-07-28 e844ef2fdab88508e7dff4bb9e7b1632fcce15b2
src/main/kotlin/cn/flightfeather/supervision/business/report/DataSource.kt
@@ -1,31 +1,394 @@
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
import cn.flightfeather.supervision.common.utils.Constant
import cn.flightfeather.supervision.common.utils.DateUtil
import cn.flightfeather.supervision.domain.ds1.entity.*
import cn.flightfeather.supervision.domain.ds1.mapper.*
import cn.flightfeather.supervision.domain.ds2.entity.LedgerRecord
import cn.flightfeather.supervision.domain.ds2.entity.LedgerSubType
import cn.flightfeather.supervision.domain.ds2.entity.UserMap
import cn.flightfeather.supervision.domain.ds2.mapper.LedgerRecordMapper
import cn.flightfeather.supervision.domain.ds2.mapper.LedgerSubTypeMapper
import cn.flightfeather.supervision.domain.ds2.mapper.UserMapMapper
import cn.flightfeather.supervision.lightshare.vo.ExcelConfigVo
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import tk.mybatis.mapper.entity.Example
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import javax.annotation.PostConstruct
/**
 * 报告所需源数据
 * 生成报告时,所需要的数据源
 * 生成报告时,统一获取各基础数据
 * @param config 生成报告的参数
 */
class DataSource {
class DataSource(val config: ExcelConfigVo, val dbMapper: DbMapper){
    private var subTask: Subtask? = null
    private val dateUtil = DateUtil()
    /**
     * 指定当前进行统计的主体对象
     */
    fun mainObj(subtask: Subtask) {
        this.subTask = subTask
    private val sourceList = mutableListOf<Subtask>()
    var year = 0
    var month = 0
    var area = ""
    val rowData = RowData()
    init {
        if (config.districtCode == null) {
            throw IllegalStateException("参数缺少区县编码:[districtCode]")
        }
        if (config.sceneType == null) {
            throw IllegalStateException("参数缺少场景类型:[sceneType]")
        }
        getSource(config)
    }
    //场景基本信息
    var scene: Scense? = null
    fun loop(callback: (index:Int, rowData: RowData) -> Unit) {
        reset()
        for (i in sourceList.indices) {
            rowData.index = i
            rowData.clear()
            rowData.subTask = sourceList[i]
            callback(i, rowData)
        }
    }
    //问题类型
    var problemTypes = mutableListOf<Problemtype>()
    /**
     * 重置
     */
    fun reset() {
        rowData.index = 0
        rowData.subTask = sourceList.first()
        rowData.clear()
    }
    //具体的问题
    var problems = mutableListOf<Problemlist>()
}
    /**
     * 数据统计的时间和区域名称
     */
    fun areaName(): String {
        val t = dbMapper.taskMapper.selectByPrimaryKey(config.topTaskGuid)
        return "${dateUtil.DateToString(t.starttime, DateUtil.DateStyle.YYYY_MM_CN)}${t.districtname}${if (area != t.districtname) area else ""}${Constant.ScenseType.getDes(config.sceneType)}"
    }
    /**
     * 获取报告数据源
     */
    private fun getSource(config: ExcelConfigVo) {
        if (config.sceneType == null) return
        val result = mutableListOf<Subtask>()
        if (config.townCode != null) {
            dbMapper.townMapper.selectByExample(Example(Town::class.java).apply {
                createCriteria().andEqualTo("towncode", config.townCode)
            })?.takeIf { it.isNotEmpty() }?.get(0)?.let { area = it.townname ?: "" }
        }
        dbMapper.taskMapper.selectByPrimaryKey(config.topTaskGuid).let {
            val time = LocalDateTime.ofInstant(it.starttime?.toInstant(), ZoneId.systemDefault())
            this.year = time.year
            this.month = time.monthValue
            if (area.isBlank()) area = it.districtname ?: ""
        }
        //1. 查找特定的巡查任务或者所有的计划巡查任务
        var taskSceneIdList = listOf<String>()
        val subTaskList = if (config.subTaskIdList?.isNotEmpty() == true ||
            (config.startTime != null || config.endTime != null)
        ) {
            dbMapper.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 = dbMapper.monitorobjectversionMapper.getSceneByType(config.topTaskGuid, config.sceneType, config.townCode)
            dbMapper.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)
        }
        sourceList.addAll(result)
    }
    inner class RowData(){
        var index = 0
        var subTask: Subtask? = null
        //场景基本信息
        val scene: Scense?
            get() {
                if (_scene == null) {
                    _scene = dbMapper.scenseMapper.selectByPrimaryKey(subTask?.scenseid)
                }
                return _scene
            }
        private var _scene: Scense? = null
        //各场景特有的基本信息
        val baseScene: BaseScene?
            get() {
                if (_baseScene == null) {
                    _baseScene = when (this.scene?.typeid.toString()) {
                        Constant.ScenseType.TYPE1.value -> {
                            dbMapper.sceneConstructionSiteMapper.selectByPrimaryKey(scene?.guid)
                        }
                        Constant.ScenseType.TYPE2.value -> {
                            dbMapper.sceneWharfMapper.selectByPrimaryKey(scene?.guid)
                        }
                        Constant.ScenseType.TYPE3.value -> {
                            dbMapper.sceneMixingPlantMapper.selectByPrimaryKey(scene?.guid)
                        }
                        Constant.ScenseType.TYPE14.value -> {
                            dbMapper.sceneStorageYardMapper.selectByPrimaryKey(scene?.guid)
                        }
                        else -> null
                    }
                }
                return _baseScene
            }
        private var _baseScene: BaseScene? = null
        //具体的问题
        val problems: MutableList<Problemlist>
            get() {
                if (noRecord()) return mutableListOf()
                if (_problems.isEmpty()) {
                    val r = dbMapper.problemlistMapper.selectByExample(Example(Problemlist::class.java).apply {
                        createCriteria().andEqualTo("stguid", subTask?.stguid)
                    })
                    _problems.addAll(r)
                }
                return _problems
            }
        private var _problems = mutableListOf<Problemlist>()
        val evaluation: Evaluation?
            get() {
                if (_evaluation == null) {
                    if (noRecord()) return null
                    dbMapper.evaluationMapper.selectByExample(Example(Evaluation::class.java).apply {
                        createCriteria().andEqualTo("stguid", subTask?.stguid)
                    })?.takeIf { it.isNotEmpty() }?.let { _evaluation = it[0] }
                }
                return _evaluation
            }
        private var _evaluation: Evaluation? = null
        val itemevaluationList: MutableList<Itemevaluation>
            get() {
                if (_itemevaluationList.isEmpty()) {
                    val r = dbMapper.itemevaluationMapper.selectByExample(Example(Itemevaluation::class.java).apply {
                        createCriteria().andEqualTo("stguid", subTask?.stguid)
                    })
                    _itemevaluationList.addAll(r)
                    println("-------------------itemevaluationList--------------------------------")
                }
                return _itemevaluationList
            }
        private var _itemevaluationList = mutableListOf<Itemevaluation>()
        //问题类型
        val problemTypes: MutableList<Problemtype>
            get() {
                if (_problemTypes.isEmpty()) {
                    val r = dbMapper.problemtypeMapper.selectByExample(Example(Problemtype::class.java).apply {
                        createCriteria().andEqualTo("scensetypeid", config.sceneType)
                            .andEqualTo("districtcode", config.districtCode)
                        orderBy("extension1")
                    })
                    _problemTypes.addAll(r)
                }
                return _problemTypes
            }
        private var _problemTypes = mutableListOf<Problemtype>()
        //自动评分规则一级分类
        val topItems: MutableList<Evaluationsubrule2>
            get() {
                if (_topItems.isEmpty()) {
                    val rule = dbMapper.evaluationruleMapper.selectByExample(Example(Evaluationrule::class.java).apply {
                        createCriteria()
                            .andEqualTo("tasktypeid", 99)
                            .andEqualTo("scensetypeid", config.sceneType)
                    })
                    if (rule.isNotEmpty()) {
                        val ruleId = rule[0].guid
                        val rules = dbMapper.evaluationsubruleMapper.selectByExample(Example(Evaluationsubrule2::class.java).apply {
                            createCriteria().andEqualTo("erguid", ruleId)
                        })
                        rules.forEach {
                            if (it.ertype == 2) {
                                _topItems.add(it)
                            }
                        }
                        _topItems.sortBy { it.displayid }
                        var t = 0
                        _topItems.forEach {
                            t += it.maxscore ?: 0
                            val tempRules = mutableListOf<Evaluationsubrule2>()
                            for (i in rules) {
                                if (i.fatherid == it.guid && i.ertype == 3) {
                                    tempRules.add(i)
                                }
                            }
                            //评分大项如果没有找到评分小项,则说明其直接对应最小评分项,其本身变成评分项
                            if (tempRules.isEmpty()) {
                                tempRules.add(it)
                            }
                            tempRules.sortBy { t -> t.displayid }
                            tempRules.forEach { temp ->
                                val tempSubRules = mutableListOf<Evaluationsubrule2>()
                                for (i in rules) {
                                    if (i.fatherid == temp.guid && i.ertype == 4) {
                                        tempSubRules.add(i)
                                    }
                                }
                                tempSubRules.sortBy { ts -> ts.displayid }
                                this._rules.add(Pair(temp, tempSubRules))
                            }
                        }
                    }
                }
                return _topItems
            }
        private var _topItems = mutableListOf<Evaluationsubrule2>()
        //自动评分规则二级和三级分类
        val rules: MutableList<Pair<Evaluationsubrule2, MutableList<Evaluationsubrule2>>>
            get() {
                if (_rules.isEmpty()) {
                    this.topItems
                }
                return _rules
            }
        private var _rules = mutableListOf<Pair<Evaluationsubrule2, MutableList<Evaluationsubrule2>>>()
        //必填台账数量
        val ledgerCount: Int
            get() {
                if (_ledgerCount == -1) {
                    val tzSceneType = Constant.ScenseType.typeMap(config.sceneType?.toByte())
                    _ledgerCount = dbMapper.ledgerSubTypeMapper.selectCountByExample(Example(LedgerSubType::class.java).apply {
                        createCriteria().andEqualTo("lScenetype", tzSceneType).andEqualTo("lNeedupdate", true)
                    })
                }
                return _ledgerCount
            }
        private var _ledgerCount = -1
        //用户实际提交台账数量
        val ledgerRecords: List<LedgerRecord>
            get() {
                if (_ledgerRecordNum == null) {
                    val userInfo = dbMapper.userinfoMapper.selectByExample(Example(Userinfo::class.java).apply {
                        createCriteria().andEqualTo("dGuid", subTask?.scenseid)
                    })?.takeIf { l -> l.isNotEmpty() }?.get(0)
                    val tzUserId = dbMapper.userMapMapper.selectByExample(Example(UserMap::class.java).apply {
                        createCriteria().andEqualTo("svUserId", userInfo?.guid)
                    })?.takeIf { m-> m.isNotEmpty() }?.get(0)?.tzUserId
                    if (tzUserId != null) {
                        _ledgerRecordNum = dbMapper.ledgerRecordMapper.selectByExample(Example(LedgerRecord::class.java).apply {
                            createCriteria().andEqualTo("lrYear", year)
                                    .andEqualTo("lrMonth", month)
                                    .andEqualTo("lrSubmitid", tzUserId)
                        })
                    }
                }
                return _ledgerRecordNum ?: emptyList()
            }
        private var _ledgerRecordNum: List<LedgerRecord>? = null
        /**
         * 获取当前巡查任务的上期巡查记录
         */
        fun lastOne(): RowData {
            val last = RowData()
            val r = dbMapper.subtaskMapper.selectByExample(Example(Subtask::class.java).apply {
                createCriteria().andEqualTo("scenseid", subTask?.scenseid)
                    .andLessThan("planstarttime", subTask?.planstarttime)
                orderBy("planstarttime").desc()
            })
            if (r.isNotEmpty()) {
                val thisMonth = LocalDateTime.ofInstant(subTask?.planstarttime?.toInstant(), ZoneId.systemDefault()).withDayOfMonth(1).toLocalDate()
                val lastMonth = LocalDateTime.ofInstant(r[0]?.planstarttime?.toInstant(), ZoneId.systemDefault()).withDayOfMonth(1).toLocalDate()
                if (lastMonth.plusMonths(1).isEqual(thisMonth)) {
                    last.subTask = r[0]
                }
            }
            return last
        }
        /**
         * 清空当前处理的对象的相关数据源
         */
        fun clear() {
            _scene = null
            _baseScene = null
            _problems.clear()
            _evaluation = null
            _itemevaluationList.clear()
            _ledgerRecordNum = null
        }
        /**
         * 判断场景是否巡查监管,有无巡查记录
         */
        fun noRecord() = subTask?.stguid == null
    }
}
data class DbMapper(
    val scenseMapper: ScenseMapper,
    val problemlistMapper: ProblemlistMapper,
    val problemtypeMapper: ProblemtypeMapper,
    val subtaskMapper: SubtaskMapper,
    val monitorobjectversionMapper: MonitorobjectversionMapper,
    val sceneConstructionSiteMapper: SceneConstructionSiteMapper,
    val sceneMixingPlantMapper: SceneMixingPlantMapper,
    val sceneStorageYardMapper: SceneStorageYardMapper,
    val sceneWharfMapper: SceneWharfMapper,
    val taskMapper: TaskMapper,
    val evaluationruleMapper: EvaluationruleMapper,
    val evaluationsubruleMapper: EvaluationsubruleMapper2,
    val evaluationMapper: EvaluationMapper,
    val itemevaluationMapper: ItemevaluationMapper,
    val ledgerSubTypeMapper: LedgerSubTypeMapper,
    val ledgerRecordMapper: LedgerRecordMapper,
    val userinfoMapper: UserinfoMapper,
    val userMapMapper: UserMapMapper,
    val townMapper: TownMapper,
)