package com.pomelotea.hoperun.sign.scheduler import com.pomelotea.hoperun.sign.common.* import com.pomelotea.hoperun.sign.config.HoperunUserConfig import com.pomelotea.hoperun.sign.config.UserConfig import java.io.BufferedWriter import java.io.File import java.io.OutputStreamWriter import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.* import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit /** * * @version 0.0.1 * @author jimlee * date 2023-03-22 14:50 * 自动打卡定时任务 **/ class AutoDakaScheduler { val outFile = File("./daka.log") val bw: BufferedWriter = BufferedWriter(OutputStreamWriter(outFile.outputStream())) val timeThreadPool: ScheduledExecutorService = Executors.newScheduledThreadPool(1) val schedulerThreadPool: ScheduledExecutorService = Executors.newScheduledThreadPool(10) init { timeThreadPool.scheduleAtFixedRate({addAutoDakaScheduled()}, 1, 60, TimeUnit.MINUTES) } companion object { val dakaQueue: MutableList = LinkedList() } fun addAutoDakaScheduled(dakaDate: String = getNowDateyyyy_MM_dd()) { // 调休的工作日 if (isNeedDaka(dakaDate)) { bw.use { HoperunUserConfig.userConfigMap.forEach { (k, v) -> if (v.autoDaka) { // 没有当日的打卡信息才插入 var daka = dakaQueue.find { it.dakaDate == dakaDate && it.employeeNo == v.employeeNo } if (daka == null) { daka = generateDakaInfo(v, dakaDate) dakaQueue.add(daka) } bw.write("${v.username},${daka.toCsv()}") bw.newLine() } } } } dakaQueue.forEach { val beginDate = LocalDateTime.parse(it.dakaDate + "T" + it.beginTime + ":" + randowSecond(), DateTimeFormatter.ISO_LOCAL_DATE_TIME) val endDate = LocalDateTime.parse(it.dakaDate + "T" + it.endTime + ":" + randowSecond(), DateTimeFormatter.ISO_LOCAL_DATE_TIME) val beginSeconds = beginDate.toEpochSecond(DEFAULT_ZONE) val endSeconds = endDate.toEpochSecond(DEFAULT_ZONE) if (beginSeconds > System.currentTimeMillis() / 1000) { schedulerThreadPool.schedule({beginDaka(it)}, beginDate.toEpochSecond(DEFAULT_ZONE), TimeUnit.SECONDS) } if (endSeconds > System.currentTimeMillis() / 1000) { schedulerThreadPool.schedule({endDaka(it)}, endDate.toEpochSecond(DEFAULT_ZONE), TimeUnit.SECONDS) } // schedulerThreadPool.schedule({beginDaka(it)}, 5, TimeUnit.SECONDS) // schedulerThreadPool.schedule({ endDaka(it) }, 5, TimeUnit.SECONDS) } dakaQueue.removeIf { it.dakaDate.compareTo(dakaDate) == -1 } } private fun beginDaka(daka: Daka) { // println("begin:${daka.toCsv()}") beginTime(employeeNo = daka.employeeNo, date = daka.dakaDate, time = daka.beginTime) } private fun endDaka(daka: Daka) { // println("end:${daka.toCsv()}") endTime(employeeNo = daka.employeeNo, date = daka.dakaDate, time = daka.beginTime) } private fun generateDakaInfo(userConfig: UserConfig, dakaDate: String): Daka { return Daka( beginTime = "09:" + (10 + Random().nextInt(19)), endTime = getRandomEndTime(), employeeNo = userConfig.employeeNo!!, dakaDate = dakaDate ) } private fun getRandomEndTime(): String { val hourArray = intArrayOf(18, 19, 20, 21, 22, 23, 20, 21, 22, 19, 18, 20) val randomHour = hourArray[Math.round(Math.random() * 9).toInt()] val randomMinute = if (randomHour == 18) { 30 + Random().nextInt(19) } else { val min = Random().nextInt(59) if (min < 10) { "0$min" } else { min } } return "$randomHour:$randomMinute" } } data class Daka( val beginTime: String, val endTime: String, val employeeNo: String, val dakaDate: String ) { fun toCsv(): String { return "$employeeNo,$dakaDate,$beginTime,$endTime" } }