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 recordSignData(SignDataParams signDataParams) { List list = buildSignData(signDataParams); return saveSignData(list,signDataParams); } @Override public Map customSignData(CustomSignDataParam param) { Map data = new HashMap<>(4); List 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 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 saveSignData(List list,SignDataParams signDataParams){ Map 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> splittedLists = splitList(list,batchSize); // 创建线程池 ExecutorService executorService = ThreadUtil.newExecutor(corePoolSize, maxPoolSize); for (List 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 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 buildSignData(SignDataParams signDataParams) { RecordSet rs = new RecordSet(); List 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> */ private List> splitList(List list, int batchSize) { List> splittedLists = new ArrayList<>(); for (int i = 0; i < list.size(); i += batchSize) { int endIndex = Math.min(i + batchSize, list.size()); List 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; } } }