package com.engine.kqsolution.service.impl ;
import cn.hutool.core.thread.ThreadUtil ;
import com.engine.core.impl.Service ;
import com.engine.kq.biz.KQShiftManagementComInfo ;
import com.engine.kq.biz.KQWorkTime ;
import com.engine.kq.entity.WorkTimeEntity ;
import com.engine.kqsolution.entity.CustomSignDataParam ;
import com.engine.kqsolution.entity.SignDataPO ;
import com.engine.kqsolution.entity.SignDataParams ;
import com.engine.kqsolution.service.SignDataSummaryService ;
import dm.jdbc.util.StringUtil ;
import lombok.SneakyThrows ;
import org.apache.commons.collections.CollectionUtils ;
import org.apache.commons.lang.StringUtils ;
import weaver.conn.RecordSet ;
import weaver.conn.RecordSetTrans ;
import weaver.general.Util ;
import weaver.hrm.resource.ResourceComInfo ;
import java.text.DecimalFormat ;
import java.time.LocalDate ;
import java.time.format.DateTimeFormatter ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.concurrent.ExecutorService ;
import java.util.stream.Collectors ;
/ * *
* @Author liang . cheng
* @Date 2023 / 9 / 18 11 : 45 AM
* @Description :
* @Version 1.0
* /
public class SignDataSummaryServiceImpl extends Service implements SignDataSummaryService {
public static final DateTimeFormatter MONTH_FORMATTER_PATTERN = DateTimeFormatter . ofPattern ( "yyyy-MM" ) ;
@Override
public Map < String , Object > recordSignData ( SignDataParams signDataParams ) {
List < SignDataPO > list = buildSignData ( signDataParams ) ;
return saveSignData ( list , signDataParams ) ;
}
@Override
public Map < String , Object > customSignData ( CustomSignDataParam param ) {
Map < String , Object > data = new HashMap < > ( 4 ) ;
List < Integer > idList = new ArrayList < > ( ) ;
//获取部门下人员id
RecordSet rs = new RecordSet ( ) ;
rs . executeQuery ( "select id from hrmresource where departmentid in (" + param . getDepartments ( ) + ")" ) ;
while ( rs . next ( ) ) {
idList . add ( Util . getIntValue ( rs . getString ( "id" ) ) ) ;
}
if ( CollectionUtils . isEmpty ( idList ) ) {
data . put ( "msg" , "部门下未存在人员" ) ;
return data ;
}
LocalDate localDate = LocalDate . parse ( param . getMonth ( ) + "-01" ) ;
String fromDate = localDate . toString ( ) ;
String toDate = localDate . withDayOfMonth ( localDate . lengthOfMonth ( ) ) . toString ( ) ;
String ids = StringUtils . join ( idList , "," ) ;
rs . executeQuery ( "select kqdate,resourceid,signindate,signintime,signoutdate,signouttime,signMins from kq_format_detail \n" +
" where kqdate >= ? and kqdate <= ?" +
" and resourceid in (" + ids + ")" , fromDate , toDate ) ;
List < SignDataPO > pos = new ArrayList < > ( ) ;
DecimalFormat decimalFormat = new DecimalFormat ( "0.00" ) ;
while ( rs . next ( ) ) {
String signInTime = Util . null2String ( rs . getString ( "signintime" ) ) ;
String signOutTime = Util . null2String ( rs . getString ( "signouttime" ) ) ;
if ( ! "" . equals ( signInTime ) ) {
signInTime = signInTime . substring ( 0 , 5 ) ;
}
if ( ! "" . equals ( signOutTime ) ) {
signOutTime = signOutTime . substring ( 0 , 5 ) ;
}
Integer signMins = Util . getIntValue ( Util . null2String ( rs . getString ( "signMins" ) ) , 0 ) ;
int resourceid = Util . getIntValue ( rs . getString ( "resourceid" ) ) ;
String kqdate = Util . null2String ( rs . getString ( "kqdate" ) ) ;
double hours = ( double ) signMins / 60 ;
double workHours ;
if ( hours < = 4.0 ) {
workHours = hours ;
} else {
workHours = Math . floor ( hours ) ;
String kqRestTime = checkKqRestTime ( String . valueOf ( resourceid ) , kqdate ) ;
if ( "1" . equals ( kqRestTime ) ) {
workHours = Math . floor ( hours - 1.0 ) ;
}
}
SignDataPO build = SignDataPO . builder ( )
. resourceId ( resourceid )
. attendanceDate ( kqdate )
. signInDate ( Util . null2String ( rs . getString ( "signindate" ) ) )
. signInTime ( signInTime )
. signOutDate ( Util . null2String ( rs . getString ( "signoutdate" ) ) )
. signOutTime ( signOutTime )
. signHours ( Double . parseDouble ( decimalFormat . format ( hours ) ) )
. workHours ( Double . parseDouble ( decimalFormat . format ( workHours ) ) )
. build ( ) ;
pos . add ( build ) ;
}
RecordSetTrans rst = new RecordSetTrans ( ) ;
if ( CollectionUtils . isNotEmpty ( pos ) ) {
try {
rst . setAutoCommit ( false ) ;
for ( SignDataPO item : pos ) {
rst . executeUpdate ( "update uf_kqgs set qdrq = ?,qdsj = ?,qtrq = ?,qtsj = ?,dkgssc = ?,sjgssc = ? where kqrq = ? and xm=? and zt = 0" , item . getSignInDate ( ) ,
item . getSignInTime ( ) , item . getSignOutDate ( ) , item . getSignOutTime ( ) , item . getSignHours ( ) , item . getWorkHours ( ) , item . getAttendanceDate ( ) , item . getResourceId ( ) ) ;
}
rst . commit ( ) ;
} catch ( Exception e ) {
rst . rollback ( ) ;
}
}
return data ;
}
@SneakyThrows
private Map < String , Object > saveSignData ( List < SignDataPO > list , SignDataParams signDataParams ) {
Map < String , Object > data = new HashMap < > ( 4 ) ;
DecimalFormat decimalFormat = new DecimalFormat ( "0.00" ) ;
RecordSetTrans rst = new RecordSetTrans ( ) ;
RecordSet rs = new RecordSet ( ) ;
ResourceComInfo rcom = new ResourceComInfo ( ) ;
int corePoolSize = 5 ;
int maxPoolSize = 10 ;
int batchSize = 200 ;
List < List < SignDataPO > > splittedLists = splitList ( list , batchSize ) ;
// 创建线程池
ExecutorService executorService = ThreadUtil . newExecutor ( corePoolSize , maxPoolSize ) ;
for ( List < SignDataPO > subList : splittedLists ) {
executorService . submit ( ( ) - > {
for ( SignDataPO signDataPo : subList ) {
String resourceId = String . valueOf ( signDataPo . getResourceId ( ) ) ;
Integer signMins = Util . getIntValue ( signDataPo . getSignMins ( ) , 0 ) ;
double hours = ( double ) signMins / 60 ;
double workHours ;
if ( hours < = 4.0 ) {
workHours = hours ;
} else {
workHours = Math . floor ( hours ) ;
String kqRestTime = checkKqRestTime ( resourceId , signDataPo . getAttendanceDate ( ) ) ;
if ( "1" . equals ( kqRestTime ) ) {
workHours = Math . floor ( hours - 1.0 ) ;
}
}
signDataPo . setCompany ( Integer . parseInt ( rcom . getSubCompanyID ( resourceId ) ) ) ;
signDataPo . setDepartment ( Integer . parseInt ( rcom . getDepartmentID ( resourceId ) ) ) ;
signDataPo . setJobTitle ( Integer . parseInt ( rcom . getJobTitle ( resourceId ) ) ) ;
signDataPo . setSignHours ( Double . parseDouble ( decimalFormat . format ( hours ) ) ) ;
signDataPo . setWorkHours ( Double . parseDouble ( decimalFormat . format ( workHours ) ) ) ;
}
} ) ;
}
// 关闭线程池
executorService . shutdown ( ) ;
while ( ! executorService . isTerminated ( ) ) {
}
try {
rst . setAutoCommit ( false ) ;
if ( CollectionUtils . isNotEmpty ( signDataParams . getIds ( ) ) ) {
for ( SignDataPO item : list ) {
rst . executeUpdate ( "update uf_kqgs set qdrq = ?,qdsj = ?,qtrq = ?,qtsj = ?,dkgssc = ?,sjgssc = ? where id = ? and zt = 0" , item . getSignInDate ( ) ,
item . getSignInTime ( ) , item . getSignOutDate ( ) , item . getSignOutTime ( ) , item . getSignHours ( ) , item . getWorkHours ( ) , item . getId ( ) ) ;
}
} else {
//同一考勤日期执行多次
rst . executeUpdate ( "delete from uf_kqgs where kqrq = ? and zt = 0" , signDataParams . getAttendanceDate ( ) ) ;
//获取锁定状态数据
List < Integer > idList = new ArrayList < > ( ) ;
rs . executeQuery ( " select xm from uf_kqgs where kqrq = ?" , signDataParams . getAttendanceDate ( ) ) ;
while ( rs . next ( ) ) {
idList . add ( Util . getIntValue ( rs . getString ( "xm" ) ) ) ;
}
list = list . stream ( )
. filter ( p - > ! idList . contains ( p . getResourceId ( ) ) )
. collect ( Collectors . toList ( ) ) ;
for ( SignDataPO item : list ) {
rst . executeUpdate ( "insert into uf_kqgs(formmodeid,xm,kqy,kqrq,zt,fb,bm,gw,qdrq,qdsj,qtrq,qtsj,dkgssc,sjgssc) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)" , signDataParams . getFormModeId ( ) , item . getResourceId ( ) ,
item . getAttendanceMonth ( ) , item . getAttendanceDate ( ) , item . getStatus ( ) , item . getCompany ( ) , item . getDepartment ( ) ,
item . getJobTitle ( ) , item . getSignInDate ( ) , item . getSignInTime ( ) , item . getSignOutDate ( ) , item . getSignOutTime ( ) ,
item . getSignHours ( ) , item . getWorkHours ( ) ) ;
}
}
rst . commit ( ) ;
data . put ( "count" , list . size ( ) ) ;
} catch ( Exception e ) {
rst . rollback ( ) ;
}
return data ;
}
/ * *
* 构 造 数 据
* @param signDataParams
* @return
* /
private List < SignDataPO > buildSignData ( SignDataParams signDataParams ) {
RecordSet rs = new RecordSet ( ) ;
List < SignDataPO > pos = new ArrayList < > ( ) ;
String formatYearMonth = getFormatLocalDate ( LocalDate . now ( ) , MONTH_FORMATTER_PATTERN ) ;
if ( StringUtil . isNotEmpty ( signDataParams . getAttendanceDate ( ) ) ) {
formatYearMonth = signDataParams . getAttendanceDate ( ) . substring ( 0 , 7 ) ;
}
if ( CollectionUtils . isNotEmpty ( signDataParams . getIds ( ) ) ) {
String ids = StringUtils . join ( signDataParams . getIds ( ) , "," ) ;
rs . executeQuery ( "select u.id,u.xm,u.kqrq,u.kqy,k.signindate,k.signintime,k.signoutdate,k.signouttime,k.signMins from uf_kqgs u inner join kq_format_detail k" +
" on u.xm = k.resourceid and u.kqrq = k.kqdate and u.zt = 0 and u.id in (" + ids + ")" ) ;
while ( rs . next ( ) ) {
String signInTime = Util . null2String ( rs . getString ( "signintime" ) ) ;
String signOutTime = Util . null2String ( rs . getString ( "signouttime" ) ) ;
if ( ! "" . equals ( signInTime ) ) {
signInTime = signInTime . substring ( 0 , 5 ) ;
}
if ( ! "" . equals ( signOutTime ) ) {
signOutTime = signOutTime . substring ( 0 , 5 ) ;
}
SignDataPO build = SignDataPO . builder ( )
. id ( Util . getIntValue ( rs . getString ( "id" ) ) )
. resourceId ( Util . getIntValue ( rs . getString ( "xm" ) ) )
. attendanceMonth ( Util . null2String ( rs . getString ( "kqy" ) ) )
. attendanceDate ( Util . null2String ( rs . getString ( "kqrq" ) ) )
. signInDate ( Util . null2String ( rs . getString ( "signindate" ) ) )
. signInTime ( signInTime )
. signOutDate ( Util . null2String ( rs . getString ( "signoutdate" ) ) )
. signOutTime ( signOutTime )
. signMins ( Util . null2String ( rs . getString ( "signMins" ) ) )
. build ( ) ;
pos . add ( build ) ;
}
} else {
rs . executeQuery ( "select resourceid,kqdate,signindate,signintime,signoutdate,signouttime,signMins from kq_format_detail where kqdate = ?" , signDataParams . getAttendanceDate ( ) ) ;
while ( rs . next ( ) ) {
String signInTime = Util . null2String ( rs . getString ( "signintime" ) ) ;
String signOutTime = Util . null2String ( rs . getString ( "signouttime" ) ) ;
if ( ! "" . equals ( signInTime ) ) {
signInTime = signInTime . substring ( 0 , 5 ) ;
}
if ( ! "" . equals ( signOutTime ) ) {
signOutTime = signOutTime . substring ( 0 , 5 ) ;
}
SignDataPO build = SignDataPO . builder ( )
. resourceId ( Util . getIntValue ( rs . getString ( "resourceid" ) ) )
. attendanceMonth ( formatYearMonth )
. attendanceDate ( Util . null2String ( rs . getString ( "kqdate" ) ) )
. status ( 0 )
. signInDate ( Util . null2String ( rs . getString ( "signindate" ) ) )
. signInTime ( signInTime )
. signOutDate ( Util . null2String ( rs . getString ( "signoutdate" ) ) )
. signOutTime ( signOutTime )
. signMins ( Util . null2String ( rs . getString ( "signMins" ) ) )
. build ( ) ;
pos . add ( build ) ;
}
}
return pos ;
}
/ * *
* @Description : 集 合 分 割
* @Author : liang . cheng
* @Date : 2023 / 9 / 13 2 : 46 PM
* @param : [ list , batchSize ]
* @return : java . util . List < java . util . List < T > >
* /
private < T > List < List < T > > splitList ( List < T > list , int batchSize ) {
List < List < T > > splittedLists = new ArrayList < > ( ) ;
for ( int i = 0 ; i < list . size ( ) ; i + = batchSize ) {
int endIndex = Math . min ( i + batchSize , list . size ( ) ) ;
List < T > subList = list . subList ( i , endIndex ) ;
splittedLists . add ( subList ) ;
}
return splittedLists ;
}
private String checkKqRestTime ( String id , String gzrq ) {
KQWorkTime kqWorkTime = new KQWorkTime ( ) ;
WorkTimeEntity workTimeEntity = kqWorkTime . getWorkTime ( id , gzrq ) ;
String serialId = workTimeEntity . getSerialId ( ) ;
if ( StringUtils . isBlank ( serialId ) | | "-1" . equals ( serialId ) ) {
kqWorkTime . setIsFormat ( true ) ;
workTimeEntity = kqWorkTime . getWorkTime ( id , gzrq ) ;
serialId = workTimeEntity . getSerialId ( ) ;
}
KQShiftManagementComInfo kqShiftManagementComInfo = new KQShiftManagementComInfo ( ) ;
return kqShiftManagementComInfo . getIsresttimeopen ( serialId ) ;
}
public String getFormatLocalDate ( LocalDate localDate , DateTimeFormatter type ) {
if ( localDate = = null ) {
return StringUtils . EMPTY ;
}
try {
return localDate . format ( type ) ;
} catch ( Exception e ) {
return StringUtils . EMPTY ;
}
}
}