2023-01-10 16:52:33 +08:00
package com.pomelotea.hoperun.sign.api
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.alibaba.fastjson.TypeReference
2023-03-22 18:10:03 +08:00
import com.pomelotea.hoperun.sign.api.model.AttendancesDetail
import com.pomelotea.hoperun.sign.api.model.AttendancesDetailResponse
import com.pomelotea.hoperun.sign.common.*
2023-01-10 16:52:33 +08:00
import com.pomelotea.hoperun.sign.config.HoperunUserConfig
2023-03-22 18:10:03 +08:00
import com.pomelotea.hoperun.sign.config.HoperunUserConfig.deviceMap
import com.pomelotea.hoperun.sign.config.HoperunUserConfig.getUserConfig
import com.pomelotea.hoperun.sign.config.HoperunUserConfig.userConfigMap
2023-01-10 16:52:33 +08:00
import com.pomelotea.hoperun.sign.config.UserConfig
2023-03-22 18:10:03 +08:00
import com.pomelotea.hoperun.sign.scheduler.AutoDakaScheduler
2023-03-22 19:34:53 +08:00
import com.pomelotea.hoperun.sign.scheduler.AutoDakaScheduler.Companion.dakaQueue
2023-01-10 16:52:33 +08:00
import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
2023-03-22 18:10:03 +08:00
import org.jsoup.Jsoup
import org.springframework.web.bind.annotation.*
2023-01-10 16:52:33 +08:00
import java.text.SimpleDateFormat
import java.util.*
/ * *
*
* @version 0.0 . 1
* @author jimlee
* date 2022 - 07 - 15 11 : 01
2023-03-22 18:10:03 +08:00
* update : 2023 / 3 / 22
2023-01-10 16:52:33 +08:00
* hoperun打卡服务接口
* * /
2023-03-22 18:10:03 +08:00
2023-01-10 16:52:33 +08:00
@RestController
@RequestMapping ( " /api/daka " )
2023-03-22 18:10:03 +08:00
class HoperunSignController {
2023-01-10 16:52:33 +08:00
2023-03-22 18:10:03 +08:00
init {
AutoDakaScheduler ( )
2023-01-10 16:52:33 +08:00
}
2023-03-22 18:10:03 +08:00
@GetMapping ( " /username/{employeeNo}/{jsessionId}/{checked} " )
fun getUsername ( @PathVariable employeeNo : String , @PathVariable jsessionId : String , @PathVariable checked : Boolean ) : WebResult < LoginResponse ? > {
getJsessionIdAutoLogin ( employeeNo , jsessionId )
val userConfig = getUserConfig ( employeeNo ) ?: return WebResult . getFailed ( " 登陆失败 " )
userConfig . autoDaka = checked
userConfig . device = deviceMap [ employeeNo ]
2023-01-10 16:52:33 +08:00
return WebResult . getSuccess (
LoginResponse (
userConfig . username ,
userConfig . device ,
userConfig . project _id ,
userConfig . projectname ,
" 杭州市 "
)
)
}
2023-03-22 18:10:03 +08:00
@GetMapping ( " /auto/{employeeNo}/{checked} " )
fun autoDaka ( @PathVariable employeeNo : String , @PathVariable checked : Boolean ) : WebResult < Any ? > {
val userConfig = getUserConfig ( employeeNo ) ?: return WebResult . getFailed ( " 需要重新登录 " )
userConfig . autoDaka = checked
return WebResult . getSuccess ( checked )
}
2023-01-10 16:52:33 +08:00
@GetMapping ( " /last/{employeeNo} " )
fun getLast5DaysRecord ( @PathVariable employeeNo : String ) : WebResult < Any ? > {
2023-03-22 18:10:03 +08:00
val jsessionId = sessionMap . get ( employeeNo ) ?: return WebResult . getFailed ( " 登陆失败 " )
2023-01-10 16:52:33 +08:00
return WebResult . getSuccess ( monthAtt ( employeeNo , jsessionId ) )
}
@PostMapping ( " /endTime " )
fun endTime ( @RequestBody request : DakaRequest ) : WebResult < Any ? > {
2023-03-22 18:10:03 +08:00
val userConfig = userConfigMap . get ( request . employeeNo )
2023-01-10 16:52:33 +08:00
if ( userConfig ?. device == null ) {
return WebResult . getFailed ( " 用户没有配置的deviceUA " )
}
2023-03-22 18:10:03 +08:00
val jsessionId = sessionMap . get ( request . employeeNo )
2023-01-10 16:52:33 +08:00
if ( jsessionId == null ) {
return WebResult . getFailed ( " 登陆失败 " )
}
val date = if ( request . date == " 今天 " ) SimpleDateFormat ( " yyyy-MM-dd " ) . format ( Date ( ) ) else request . date
val dakaRequest = Request . Builder ( )
. url ( DAKA _URL )
. post (
JSON . toJSONString (
endTimeHoperunDakaRequest (
request . employeeNo ,
date ,
request . time
)
) . toRequestBody ( " application/json;charset=utf-8 " . toMediaTypeOrNull ( ) )
)
. addHeader ( " Cookie " , " JSESSIONID= $jsessionId " )
. build ( )
val result : String ? = client . newCall ( dakaRequest ) . execute ( ) . body ?. string ( )
return WebResult . getSuccess ( JSONObject . parseObject ( result , DakaResponse :: class . java ) )
}
@PostMapping ( " /beginTime " )
fun beginTime ( @RequestBody request : DakaRequest ) : WebResult < Any ? > {
2023-03-22 18:10:03 +08:00
val userConfig = userConfigMap . get ( request . employeeNo )
2023-01-10 16:52:33 +08:00
if ( userConfig ?. device == null ) {
return WebResult . getFailed ( " 用户没有配置的deviceUA " )
}
2023-03-22 18:10:03 +08:00
val jsessionId = sessionMap . get ( request . employeeNo )
2023-01-10 16:52:33 +08:00
val date = if ( request . date == " 今天 " ) SimpleDateFormat ( " yyyy-MM-dd " ) . format ( Date ( ) ) else request . date
val dakaRequest = Request . Builder ( )
. url ( DAKA _URL )
. post (
JSON . toJSONString (
beginTimeHoperunDakaRequest (
request . employeeNo ,
date ,
request . time
)
) . toRequestBody ( " application/json;charset=utf-8 " . toMediaTypeOrNull ( ) )
)
. addHeader ( " Cookie " , " JSESSIONID= $jsessionId " )
. build ( )
val result : String ? = client . newCall ( dakaRequest ) . execute ( ) . body ?. string ( )
return WebResult . getSuccess ( JSONObject . parseObject ( result , DakaResponse :: class . java ) )
}
2023-03-22 18:10:03 +08:00
private fun getJsessionIdAutoLogin ( employeeNo : String , jsessionId : String ) : String ? {
if ( sessionMap . get ( employeeNo ) == null ) {
login ( employeeNo , jsessionId )
2023-01-10 16:52:33 +08:00
}
return sessionMap . get ( employeeNo )
}
/ * *
* 查询近两个月的
* /
private fun monthAtt ( employeeNo : String , jsessionId : String ) : List < MonthAttLog > {
val monthAttResult : MutableList < MonthAttLog > = ArrayList ( )
val monthAttList : List < MonthAttLog > = queryMonthAttData ( employeeNo , jsessionId , getNowDateyyyy _MM ( ) + " -01 " )
// 如果dateType = 1的结果小于3条, 查询上月
val monthAttLogs = monthAttList . sortedByDescending { it . yearmonth } . filter { it . dateType == " 1 " }
. filter { it . yearmonth !! . compareTo ( getNowDateyyyy _MM _dd ( ) ) <= 0 }
monthAttResult . addAll ( monthAttLogs )
val lastMonthAttList : List < MonthAttLog > =
queryMonthAttData ( employeeNo , jsessionId , getLastDateyyyy _MM ( ) + " -01 " )
val lastMonthAttLogs = lastMonthAttList . sortedByDescending { it . yearmonth } . filter { it . dateType == " 1 " }
monthAttResult . addAll ( lastMonthAttLogs )
2023-03-22 19:34:53 +08:00
val monthAttLog = monthAttResult . find { it . yearmonth == getNowDateyyyy _MM _dd ( ) }
val autoDaka = dakaQueue . filter { it . dakaDate == getNowDateyyyy _MM _dd ( ) } . findLast { it . employeeNo == employeeNo }
if ( autoDaka != null && monthAttLog != null ) {
monthAttLog . autoDakaBeginTime = autoDaka . beginTime
monthAttLog . autoDakaEndTime = autoDaka . endTime
}
2023-01-10 16:52:33 +08:00
return monthAttResult
}
private fun queryMonthAttData ( employeeNo : String , jsessionId : String , yearmonth : String ) : List < MonthAttLog > {
val monthAttRequest = Request . Builder ( )
. url ( MONTH _ATT _URL )
. post (
FormBody . Builder ( )
. add ( " staff_code " , padEmployeeNumber ( employeeNo ) )
. add ( " yearmonth " , yearmonth )
. build ( )
)
. addHeader ( " Cookie " , " JSESSIONID= $jsessionId " )
. build ( )
val result : String ? = client . newCall ( monthAttRequest ) . execute ( ) . body ?. string ( )
return JSONObject . parseObject (
JSONObject . parseObject ( result ) . getString ( " data " ) ,
object : TypeReference < List < MonthAttLog > ? > ( ) { } )
}
2023-03-22 18:10:03 +08:00
private fun login ( employeeNo : String , jsessionId : String ) {
2023-01-10 16:52:33 +08:00
// 读取员工姓名
2023-03-22 18:10:03 +08:00
if ( userConfigMap [ employeeNo ] ?. username == null ) {
setUserConfig ( employeeNo , jsessionId )
sessionMap . put ( employeeNo , jsessionId )
2023-01-10 16:52:33 +08:00
}
}
2023-03-22 18:10:03 +08:00
private fun setUserConfig ( employeeNo : String , jsessionId : String ) {
2023-01-10 16:52:33 +08:00
val attendancesDetailRequest = Request . Builder ( )
2023-03-22 18:10:03 +08:00
. url ( " http://pom.hoperun.com:8187/attm/calendar/monthAtt?staff_code= ${padEmployeeNumber(employeeNo)} &yearmonth= ${getNowDateyyyy_MM()} -01 " )
. get ( )
2023-01-10 16:52:33 +08:00
. addHeader ( " Cookie " , " JSESSIONID= $jsessionId " )
2023-03-22 18:10:03 +08:00
. addHeader ( " User-Agent " , " Qing/0.9.113;iOS 16.3.1;Apple;iPhone13,2;deviceId:a8baf66f-fdeb-4f4d-b1e5-9fafcd5045b6;deviceName:iOS;clientId:10200;os:iOS 16.3.1;brand:Apple;model:iPhone13,2;lang:zh-CN;fontNum:0;fontScale:1.0;ver:10.7.14;Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 " )
. addHeader ( " accept " , " */* " )
. addHeader ( " Origin " , " http://pom.hoperun.com:8187 " )
. addHeader ( " Referer " , " http://pom.hoperun.com:8187/attm/attence/getInfo " )
. addHeader ( " content-type " , " application/x-www-form-urlencoded; charset=UTF-8 " )
2023-01-10 16:52:33 +08:00
. build ( )
2023-03-22 18:10:03 +08:00
val attendancesDetailResp = client . newCall ( attendancesDetailRequest ) . execute ( )
val bodyString = attendancesDetailResp . body ?. string ( )
val attendancesDetailResponse = JSONObject . parseObject ( bodyString , AttendancesDetailResponse :: class . java )
val dataList : List < AttendancesDetail > = JSONObject . parseObject ( attendancesDetailResponse . data , object : TypeReference < List < AttendancesDetail > > ( ) { } )
val lastDakaInfo : AttendancesDetail = dataList
. filter { it . project _id != " -1 " }
. findLast { it . yearmonth == " 2023-03-21 " } !!
val userConfig : UserConfig = userConfigMap . get ( employeeNo ) ?: UserConfig ( )
2023-01-10 16:52:33 +08:00
if ( userConfig . projectcode == null ) {
2023-03-22 18:10:03 +08:00
userConfig . projectcode = lastDakaInfo . projectcode
2023-01-10 16:52:33 +08:00
}
if ( userConfig . projectname == null ) {
2023-03-22 18:10:03 +08:00
userConfig . projectname = lastDakaInfo . projectname
2023-01-10 16:52:33 +08:00
}
if ( userConfig . project _id == null ) {
2023-03-22 18:10:03 +08:00
userConfig . project _id = lastDakaInfo . project _id
2023-01-10 16:52:33 +08:00
}
2023-03-22 18:10:03 +08:00
// username 要从主页的html元素中获取
val indexRequest = Request . Builder ( )
. url ( " http://pom.hoperun.com:8187/attm/attence/getInfo " )
. get ( )
. addHeader ( " Cookie " , " JSESSIONID= $jsessionId " )
. addHeader ( " User-Agent " , " Qing/0.9.113;iOS 16.3.1;Apple;iPhone13,2;deviceId:a8baf66f-fdeb-4f4d-b1e5-9fafcd5045b6;deviceName:iOS;clientId:10200;os:iOS 16.3.1;brand:Apple;model:iPhone13,2;lang:zh-CN;fontNum:0;fontScale:1.0;ver:10.7.14;Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 " )
. addHeader ( " accept " , " */* " )
. addHeader ( " Origin " , " http://pom.hoperun.com:8187 " )
. addHeader ( " Referer " , " http://pom.hoperun.com:8187/attm/attence/getInfo " )
. addHeader ( " content-type " , " application/x-www-form-urlencoded; charset=UTF-8 " )
. build ( )
val indexResp = client . newCall ( indexRequest ) . execute ( )
val indexHtml = indexResp . body ?. string ( )
val doc = Jsoup . parse ( indexHtml !! )
userConfig . username = doc . select ( " #attendance-detail-content > div.container.none-padding > div > div:nth-child(1) > div:nth-child(4) " ) . text ( )
userConfig . employeeNo = employeeNo
HoperunUserConfig . addUserConfig (
2023-01-10 16:52:33 +08:00
employeeNo , userConfig
)
}
}
data class DakaRequest (
val employeeNo : String ,
val date : String ,
val time : String
)
data class DakaResponse (
var result : String ? = null ,
var comment : String ? = null ,
var data : String ? = null
)
class WebResult < T > protected constructor ( ) : java . io . Serializable {
var data : T ? = null
var code : Int ? = null
var success = false
var message : String ? = null
@Suppress ( " UNUSED " )
var timestamp = System . currentTimeMillis ( )
companion object {
fun < T > getSuccess ( data : T ) : WebResult < T > {
return getWebResult ( true , data , " success " , 0 )
}
fun < T > getFailed ( message : String = " failed " ) : WebResult < T ? > {
return getWebResult ( false , null , message , - 1 )
}
fun < T > getWebResult ( success : Boolean , data : T , message : String ? , code : Int ? ) : WebResult < T > {
val webResult = WebResult < T > ( )
webResult . success = success
webResult . data = data
webResult . code = code
webResult . message = message
return webResult
}
}
}
data class MonthAttLog (
var area _id : String ? = null ,
var area _id _begin : String ? = null ,
var area _id _end : String ? = null ,
var attState : String ? = null ,
var att _type : String ? = null ,
var begin _time : String ? = null ,
var dateType : String ? = null ,
var departmentcode : String ? = null ,
var end _time : String ? = null ,
var project _id : String ? = null ,
var projectcode : String ? = null ,
var staff _code : String ? = null ,
2023-03-22 19:34:53 +08:00
var yearmonth : String ? = null ,
var autoDakaBeginTime : String ? = null ,
var autoDakaEndTime : String ? = null ,
2023-01-10 16:52:33 +08:00
)
data class HoperunDakaRequest (
val staff _code : String ,
val yearmonth : String ,
var project _id : String = " U2103S000078 " ,
var projectname : String = " JRKF-银河资产对接合作平台贷项目 " ,
var projectcode : String = " U2103S000078 " ,
val area _id : String = " 杭州市 " ,
val actualArea : String ,
var begin _time : String ? = null ,
var end _time : String ? = null
)
data class LoginResponse (
var username : String ? = null ,
var device : String ? = null ,
var project _id : String ? = null ,
var projectname : String ? = null ,
var area : String ? = null
)