数据同步定时器全打开提交
This commit is contained in:
parent
1f27df6e64
commit
a3b07c2b9c
|
|
@ -20,10 +20,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
|
@ -60,18 +60,19 @@ public class AttTasks {
|
|||
private volatile boolean executed = false; // 标志位,表示任务是否已经执行过
|
||||
|
||||
// @Scheduled(cron = "0 0/10 * * * ?")
|
||||
@Scheduled(fixedDelay = 60000 * 10)
|
||||
// @Scheduled(fixedDelay = 60000 * 10)
|
||||
@Async
|
||||
public void getAttTasks() {
|
||||
log.info("--------考勤定时器开启------");
|
||||
String today = DateUtil.today();
|
||||
pushAttData(today,1);
|
||||
pushAttData(today, 1);
|
||||
log.info("--------考勤定时器完毕------");
|
||||
}
|
||||
|
||||
/**
|
||||
* 历史考勤数据
|
||||
*/
|
||||
@Scheduled(fixedDelay = 60000 * 30)
|
||||
// @Scheduled(fixedDelay = 60000 * 30)
|
||||
@Async
|
||||
public void getHisAttTasks() {
|
||||
log.info("--------考勤定时器开启------");
|
||||
|
|
@ -79,8 +80,8 @@ public class AttTasks {
|
|||
return; // 如果任务已经执行过,直接返回
|
||||
}
|
||||
executed = true; // 设置标志位,表示任务已经执行过
|
||||
String startDate = "2024-11-30";
|
||||
String endDate = "2024-12-01";
|
||||
String startDate = "2024-11-20";
|
||||
String endDate = "2024-11-21";
|
||||
List<String> dateList = getStrDateListBetween(startDate, endDate);
|
||||
// 创建固定大小的线程池
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
|
||||
|
|
@ -119,24 +120,25 @@ public class AttTasks {
|
|||
|
||||
/**
|
||||
* 推送考勤数据
|
||||
*
|
||||
* @param pushDate 时间
|
||||
* @param pushType 1:自动推送 2:手动
|
||||
*/
|
||||
private void pushAttData(String pushDate,int pushType) {
|
||||
private void pushAttData(String pushDate, int pushType) {
|
||||
//获取黔送云的考勤数据
|
||||
getQsyAttendanceData(pushDate,pushType);
|
||||
getQsyAttendanceData(pushDate, pushType);
|
||||
//获取考勤机中的考勤数据
|
||||
getMachineAttendanceData(pushDate,pushType);
|
||||
getMachineAttendanceData(pushDate, pushType);
|
||||
// //查出每一个考勤组的应出勤天数以及考勤组的规则
|
||||
List<AttGroupBean> groupList = getGroupData(pushDate,pushType);
|
||||
List<AttGroupBean> groupList = getGroupData(pushDate, pushType);
|
||||
// //新增默认考勤数据到考勤数据和修改表
|
||||
insertAttData(groupList,pushDate,pushType);
|
||||
insertAttData(groupList, pushDate, pushType);
|
||||
//更新请假数据
|
||||
updateLeaveData(pushDate);
|
||||
//修改考勤数据
|
||||
updateAttData(groupList,pushDate,pushType);
|
||||
updateAttData(groupList, pushDate, pushType);
|
||||
// 根据考勤数据生成报表数据
|
||||
createReportData(groupList,pushDate,pushType);
|
||||
createReportData(groupList, pushDate, pushType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -337,7 +339,7 @@ public class AttTasks {
|
|||
return new ArrayList<>();
|
||||
}
|
||||
//查询前三天是否有节假日或补班
|
||||
List<Holiday> holidays = attSourceDataDao.selectHolidayByMonth(pushDate,pushType);
|
||||
List<Holiday> holidays = attSourceDataDao.selectHolidayByMonth(pushDate, pushType);
|
||||
groupList.forEach(c -> {
|
||||
//应考勤天
|
||||
List<String> attDayList = WorkdayCalculator.getWorkDay(c.getAttDay(),
|
||||
|
|
@ -352,7 +354,7 @@ public class AttTasks {
|
|||
*
|
||||
* @param groupList 考勤组集合
|
||||
*/
|
||||
private void insertAttData(List<AttGroupBean> groupList,String pushDate, int pushType) {
|
||||
private void insertAttData(List<AttGroupBean> groupList, String pushDate, int pushType) {
|
||||
//获取所有的用户
|
||||
List<AttDataBean> listPerson = attSourceDataDao.getAllPerson();
|
||||
if (!listPerson.isEmpty()) {
|
||||
|
|
@ -378,7 +380,7 @@ public class AttTasks {
|
|||
//查询能修改的考勤模版数据是否已经插入
|
||||
// 判断 pushDate 是否在今天之前
|
||||
boolean isPastDate = isBeforeToday(pushDate);
|
||||
if(isPastDate){
|
||||
if (isPastDate) {
|
||||
v.setAttStatus("3");
|
||||
}
|
||||
attSourceDataDao.insertAttData(v);
|
||||
|
|
@ -408,9 +410,9 @@ public class AttTasks {
|
|||
/**
|
||||
* 将未打卡的全部置为旷工
|
||||
*
|
||||
* @param v 考勤数据
|
||||
* @param type 0表示考勤数据,1表示考勤修改数据
|
||||
* @param update 0表示修改考勤数据,1表示修改考勤修改数据
|
||||
* @param v 考勤数据
|
||||
* @param type 0表示考勤数据,1表示考勤修改数据
|
||||
* @param update 0表示修改考勤数据,1表示修改考勤修改数据
|
||||
* @param pushDate 推送时间
|
||||
*/
|
||||
private void changeAbsenteeAttStatus(AttDataBean v, int type, int update, String pushDate) {
|
||||
|
|
@ -487,6 +489,7 @@ public class AttTasks {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改考勤数据
|
||||
*
|
||||
|
|
@ -494,7 +497,7 @@ public class AttTasks {
|
|||
*/
|
||||
private void updateAttData(List<AttGroupBean> groupList, String pushDate, int pushType) {
|
||||
//查出最近三天的人员考勤记录
|
||||
AtomicReference<List<AttSourceDataBean>> sourceDataList = new AtomicReference<>(attSourceDataDao.getSourceAttData(pushDate,pushType));
|
||||
AtomicReference<List<AttSourceDataBean>> sourceDataList = new AtomicReference<>(attSourceDataDao.getSourceAttData(pushDate, pushType));
|
||||
//根据考勤组的规则和请假记录算出人员的考勤状态
|
||||
groupList.forEach(c -> {
|
||||
List<AttSourceDataBean> list = Collections.emptyList();
|
||||
|
|
@ -520,7 +523,7 @@ public class AttTasks {
|
|||
list.removeIf(record -> {
|
||||
String attType = record.getAttType();
|
||||
String attCurrentTime = record.getAttCurrentTime();
|
||||
if(!"".equals(attCurrentTime)) {
|
||||
if (!"".equals(attCurrentTime)) {
|
||||
if (attCurrentTime.contains(" ")) {
|
||||
attCurrentTime = attCurrentTime.split(" ")[0];
|
||||
}
|
||||
|
|
@ -530,7 +533,7 @@ public class AttTasks {
|
|||
boolean condition1 = "2".equals(attType) && localTime.isAfter(LocalTime.of(5, 0)) && localTime.isBefore(LocalTime.of(12, 0));
|
||||
boolean condition2 = "1".equals(attType) && localTime.isAfter(LocalTime.of(12, 0)) && localTime.isBefore(LocalTime.of(23, 59));
|
||||
return condition1 || condition2;
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
@ -639,6 +642,12 @@ public class AttTasks {
|
|||
private List<AttSourceDataBean> GroupFixedData(List<AttSourceDataBean> list,
|
||||
AttGroupBean attGroupBean) {
|
||||
List<AttSourceDataBean> newList = getDataList(list, attGroupBean, false);
|
||||
Iterator<AttSourceDataBean> iterator = newList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next() == null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
processAttendanceStatus(newList, attGroupBean.getToWorkTime(), attGroupBean.getOffWorkTime(), attGroupBean.getLateMinute(),
|
||||
attGroupBean.getAbsenteeismLateMinute(), attGroupBean.getLeaveMinute(), attGroupBean.getAbsenteeismLeaveMinute());
|
||||
return newList;
|
||||
|
|
@ -656,7 +665,7 @@ public class AttTasks {
|
|||
AttGroupBean attGroupBean,
|
||||
Boolean tf) {
|
||||
List<AttSourceDataBean> newList = new ArrayList<>();
|
||||
//分组排序
|
||||
//分组排序(将每个人每天在自己考勤组的数据分组)
|
||||
Map<String, List<AttSourceDataBean>> groupedItems = list.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
c -> c.getUserId() + "|" + c.getOrgId() + "|" + c.getAttCurrentDay(),
|
||||
|
|
@ -668,6 +677,11 @@ public class AttTasks {
|
|||
}
|
||||
)
|
||||
));
|
||||
|
||||
if (!tf) {
|
||||
//固定打卡,以最靠近上班打卡时间前的出闸机的时间为基准,去除掉之前的所有打卡数据
|
||||
processGroupedItems(groupedItems, attGroupBean);
|
||||
}
|
||||
groupedItems.forEach((c, v) -> {
|
||||
//第一次上班时间
|
||||
AttSourceDataBean frontToWorkBean = v.stream()
|
||||
|
|
@ -679,50 +693,146 @@ public class AttTasks {
|
|||
.filter(a -> a.getAttType().equals("2"))
|
||||
.collect(Collectors.toList())
|
||||
.stream().max(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null);
|
||||
|
||||
if (tf) {
|
||||
//自由打卡不需要去除数据
|
||||
getFreeAttData(newList, frontToWorkBean, backOffWorkBean, attGroupBean);
|
||||
} else {
|
||||
|
||||
if (backOffWorkBean != null) {
|
||||
//最新一次下班时间插入list
|
||||
newList.add(backOffWorkBean);
|
||||
}
|
||||
//第一次下班时间
|
||||
AttSourceDataBean frontOffWorkBean = v.stream()
|
||||
.filter(a -> a.getAttType().equals("2"))
|
||||
.collect(Collectors.toList())
|
||||
.stream().min(Comparator.comparing(AttSourceDataBean::getAttCurrentTime)).orElse(null);
|
||||
if (frontToWorkBean != null) {
|
||||
if (frontOffWorkBean != null) {
|
||||
//判断第一次上班卡和第一次下班卡间隙是否符合要求
|
||||
long minute = DateUtil.between(DateUtils.parseDate(frontToWorkBean.getAttCurrentTime()),
|
||||
DateUtils.parseDate(frontOffWorkBean.getAttCurrentTime()), DateUnit.MINUTE);
|
||||
if (minute < attGroupBean.getEntryAbnormalMinute()) {
|
||||
frontToWorkBean.setAbnormalAttTime(frontOffWorkBean.getAttCurrentTime());
|
||||
frontToWorkBean.setAbnormalAttAddress(frontOffWorkBean.getAttAddress());
|
||||
frontToWorkBean.setAttStatus(8);
|
||||
} else if (minute < 20) {
|
||||
//出入异常状态判断问题(早上如果先在宏业大厦考勤机打卡,20分钟之内又在解放西路考勤机打卡;
|
||||
// 或者先在解放西路考勤机打卡,20分钟之内又在宏业大厦考勤机打卡,此种情况也记为出入异常)
|
||||
// 检查地址是否满足条件
|
||||
// 获取地址
|
||||
String toWorkAddress = frontToWorkBean.getAttAddress();
|
||||
String offWorkAddress = frontOffWorkBean.getAttAddress();
|
||||
if (toWorkAddress.startsWith("解放路") && offWorkAddress.startsWith("宏业大厦")
|
||||
|| toWorkAddress.startsWith("宏业大厦") && offWorkAddress.startsWith("解放路")) {
|
||||
frontToWorkBean.setAbnormalAttTime(frontOffWorkBean.getAttCurrentTime());
|
||||
frontToWorkBean.setAbnormalAttAddress(frontOffWorkBean.getAttAddress());
|
||||
frontToWorkBean.setAttStatus(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
//没有下班卡则添加第一次打卡数据
|
||||
newList.add(frontToWorkBean);
|
||||
if(v.get(0).getName().equals("肖阳")){
|
||||
System.out.println("c.getAttCurrentTime() = ");
|
||||
}
|
||||
// 处理逻辑 出入异常的逻辑
|
||||
Map<Boolean, List<AttSourceDataBean>> result = checkAdjacentAttType1WithGapAndCheckTypesBefore(v,attGroupBean.getEntryAbnormalMinute());
|
||||
if (result.containsKey(true)) {
|
||||
List<AttSourceDataBean> matchingItems = result.get(true);
|
||||
frontToWorkBean = matchingItems.get(0);
|
||||
frontToWorkBean.setAbnormalAttTime(matchingItems.get(1).getAttCurrentTime());
|
||||
frontToWorkBean.setAbnormalAttAddress(matchingItems.get(1).getAttAddress());
|
||||
frontToWorkBean.setAttStatus(8);
|
||||
}
|
||||
//没有下班卡则添加第一次打卡数据
|
||||
newList.add(frontToWorkBean);
|
||||
}
|
||||
});
|
||||
return newList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据getAttCurrentTime对List<AttSourceDataBean>进行正序排序。
|
||||
* 遍历排序后的列表,找到最早相邻且间隔时间大于2分钟的两个attType = 1的数据项。
|
||||
* 检查这两个数据项之前的数据集合是否同时包含attType = 1和attType = 2的数据。
|
||||
* @param items
|
||||
* @param entryAbnormalMinute
|
||||
* @return
|
||||
*/
|
||||
private Map<Boolean, List<AttSourceDataBean>> checkAdjacentAttType1WithGapAndCheckTypesBefore(List<AttSourceDataBean> items, Long entryAbnormalMinute) {
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
// 步骤1:根据 getAttCurrentTime 排序
|
||||
items.sort(Comparator.comparing(AttSourceDataBean::getAttCurrentTime));
|
||||
// 步骤2:找到最早相邻且间隔时间大于2分钟的两个 attType = 1 的数据项
|
||||
AttSourceDataBean firstAttType1 = null;
|
||||
AttSourceDataBean secondAttType1 = null;
|
||||
for (int i = 0; i < items.size() - 1; i++) {
|
||||
if ("1".equals(items.get(i).getAttType()) && "1".equals(items.get(i + 1).getAttType())) {
|
||||
// 提取时间部分
|
||||
String firstTimeStr = items.get(i).getAttCurrentTime().substring(11);
|
||||
String secondTimeStr = items.get(i + 1).getAttCurrentTime().substring(11);
|
||||
LocalTime firstTime = LocalTime.parse(firstTimeStr, timeFormatter);
|
||||
LocalTime secondTime = LocalTime.parse(secondTimeStr, timeFormatter);
|
||||
Duration duration = Duration.between(firstTime, secondTime);
|
||||
if (duration.toMinutes() > entryAbnormalMinute) {
|
||||
firstAttType1 = items.get(i);
|
||||
secondAttType1 = items.get(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果没有找到符合条件的两个 attType = 1 的数据项,直接返回 false
|
||||
if (firstAttType1 == null || secondAttType1 == null) {
|
||||
Map<Boolean, List<AttSourceDataBean>> result = new HashMap<>();
|
||||
result.put(false, Collections.emptyList());
|
||||
return result;
|
||||
}
|
||||
|
||||
// 步骤3:检查这两个数据项之前的数据集合是否同时包含 attType = 1 和 attType = 2 的数据
|
||||
int indexFirstAttType1 = items.indexOf(firstAttType1);
|
||||
List<AttSourceDataBean> dataBeforeFirstAttType1 = items.subList(0, indexFirstAttType1);
|
||||
|
||||
Set<String> attTypesBefore = dataBeforeFirstAttType1.stream()
|
||||
.map(AttSourceDataBean::getAttType)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
boolean containsBothTypes = attTypesBefore.contains("1") && attTypesBefore.contains("2");
|
||||
// 返回结果
|
||||
Map<Boolean, List<AttSourceDataBean>> result = new HashMap<>();
|
||||
if (containsBothTypes) {
|
||||
result.put(true, Arrays.asList(firstAttType1, secondAttType1));
|
||||
} else {
|
||||
result.put(false, Collections.emptyList());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 固定打卡清除数据
|
||||
*
|
||||
* @param groupedItems
|
||||
*/
|
||||
private void processGroupedItems(Map<String, List<AttSourceDataBean>> groupedItems, AttGroupBean attGroupBean) {
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
for (Map.Entry<String, List<AttSourceDataBean>> entry : groupedItems.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<AttSourceDataBean> items = entry.getValue();
|
||||
if (items.isEmpty()) {
|
||||
continue; // 如果列表为空,跳过
|
||||
}
|
||||
|
||||
// 获取上班时间并转换为 LocalTime 以便比较
|
||||
LocalTime toWorkTime = LocalTime.parse(attGroupBean.getToWorkTime(), timeFormatter);
|
||||
// 初始化变量来保存最接近上班时间的数据项及其索引
|
||||
AttSourceDataBean closestBeforeToWork = null;
|
||||
int closestIndex = -1;
|
||||
// 遍历并查找最接近上班时间且 attType=2 的数据项
|
||||
//前面已经排过序了,取第一个就可以了
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
AttSourceDataBean item = items.get(i);
|
||||
// System.out.println(item.getName());
|
||||
// if("王义".equals(item.getName())){
|
||||
// System.out.println(111);
|
||||
// }
|
||||
if ("2".equals(item.getAttType())) {
|
||||
// 只提取时间部分进行比较
|
||||
LocalTime recordTime = LocalTime.parse(item.getAttCurrentTime().substring(11), timeFormatter);
|
||||
// 检查是否在上班时间之前并且是目前找到的最接近上班时间的
|
||||
if (recordTime.isBefore(toWorkTime) &&
|
||||
(closestBeforeToWork == null ||
|
||||
recordTime.isAfter(LocalTime.parse(closestBeforeToWork.getAttCurrentTime().substring(11), timeFormatter)))) {
|
||||
closestBeforeToWork = item;
|
||||
closestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找到了符合条件的数据项,则移除它之前的所有数据,包括它自己
|
||||
if (closestIndex != -1) {
|
||||
List<AttSourceDataBean> filteredItems = items.stream()
|
||||
.skip(closestIndex) // 跳过最接近上班时间的数据项及其之前的所有数据
|
||||
.collect(Collectors.toList());
|
||||
// 更新原始映射中的列表
|
||||
groupedItems.put(key, filteredItems);
|
||||
} else {
|
||||
// 如果没有找到符合条件的数据项,可以选择保留所有数据或清空列表
|
||||
// groupedItems.put(key, Collections.emptyList()); // 清空列表
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自由考勤数据
|
||||
*
|
||||
|
|
@ -843,9 +953,10 @@ public class AttTasks {
|
|||
long absenteeismLateMinute, long leaveMinute,
|
||||
long absenteeismLeaveMinute) {
|
||||
newList.forEach(c -> {
|
||||
// if(c.getName().equals("祝捷")){
|
||||
// if(c.getName().equals("肖阳")){
|
||||
// System.out.println("c.getAttCurrentTime() = " + c.getAttCurrentTime());
|
||||
// }
|
||||
System.out.println(c.getName());
|
||||
int attStatus = calculateStatus(
|
||||
c.getAttType(),
|
||||
c.getAttCurrentTime(),
|
||||
|
|
@ -853,6 +964,7 @@ public class AttTasks {
|
|||
"1".equals(c.getAttType()) ? lateMinute : leaveMinute,
|
||||
"1".equals(c.getAttType()) ? absenteeismLateMinute : absenteeismLeaveMinute
|
||||
);
|
||||
System.out.println(1111);
|
||||
// 如打卡状态为正常,检查是否有异常出入时间
|
||||
if (attStatus == 1 && c.getAttStatus() != null && c.getAttStatus() == 8) {
|
||||
attStatus = 8; // 异常
|
||||
|
|
@ -869,6 +981,7 @@ public class AttTasks {
|
|||
c.setAttCurrentTime(time);
|
||||
c.setAttAddress(address);
|
||||
}
|
||||
System.out.println(2222);
|
||||
c.setAttStatus(attStatus);
|
||||
});
|
||||
}
|
||||
|
|
@ -929,7 +1042,7 @@ public class AttTasks {
|
|||
*/
|
||||
private void createReportData(List<AttGroupBean> groupList, String pushDate, int pushType) {
|
||||
//日报表查询
|
||||
List<AttDayReportBean> dayReportList = attSourceDataDao.selectAttDayReport(pushDate,pushType);
|
||||
List<AttDayReportBean> dayReportList = attSourceDataDao.selectAttDayReport(pushDate, pushType);
|
||||
//日报表新增
|
||||
attSourceDataDao.insertAttDayReport(dayReportList);
|
||||
//月报表查询
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class WechatTasks {
|
|||
* 人员基础数据同步定时器
|
||||
*/
|
||||
// @Scheduled(cron = "0 0/10 * * * ?")
|
||||
@Scheduled(initialDelay = 1000 * 6,fixedDelay = 60000 * 10)
|
||||
// @Scheduled(initialDelay = 1000 * 6,fixedDelay = 60000 * 10)
|
||||
@Async
|
||||
public void pushPersonTask() {
|
||||
log.info("--------人员基础数据同步定时器开启------");
|
||||
|
|
@ -98,7 +98,7 @@ public class WechatTasks {
|
|||
/**
|
||||
* 休假出差数据同步定时器
|
||||
*/
|
||||
@Scheduled(initialDelay = 1000 * 12,fixedDelay = 60000 * 10)
|
||||
@Scheduled(fixedDelay = 60000 * 10)
|
||||
@Async
|
||||
public void leaveTask() {
|
||||
log.info("--------休假出差数据定时器开启------");
|
||||
|
|
@ -110,6 +110,9 @@ public class WechatTasks {
|
|||
List<EvectionBean> list = FastJsonHelper.jsonArrStrToBeanList(string, EvectionBean.class);
|
||||
//将所有人数据更新组织机构
|
||||
for (EvectionBean bean : list) {
|
||||
if(bean.getId() != 0L){
|
||||
continue;
|
||||
}
|
||||
// 如果Map中没有该userId的组织机构信息,则从数据库查询
|
||||
SysOrg orgInfo = dao.getOrgInfoByUserId(bean.getUserId());
|
||||
if (orgInfo != null) {
|
||||
|
|
@ -124,28 +127,57 @@ public class WechatTasks {
|
|||
}
|
||||
//删除所有已经同步过去的数据
|
||||
// dao.deleteWechatLeave();
|
||||
String jsonStr3 = "{}";
|
||||
String method3 = "deleteWechatLeave";
|
||||
String string3 = httpPost(method3, jsonStr3);
|
||||
// String jsonStr3 = "{}";
|
||||
// String method3 = "deleteWechatLeave";
|
||||
// String string3 = httpPost(method3, jsonStr3);
|
||||
//在将所有数据同步过去
|
||||
List<EvectionBean> webList = dao.getWebLeaveList();
|
||||
webList.forEach(bean -> {
|
||||
// dao.insertWechatLeave(bean);
|
||||
bean.setUuid(UUID.randomUUID().toString());
|
||||
String jsonStr2 = FastJsonHelper.beanToJsonStr(bean);
|
||||
String method2 = "insertWechatLeave";
|
||||
String string2 = httpPost(method2, jsonStr2);
|
||||
});
|
||||
String jsonStr2 = "{}";
|
||||
String method2 = "getWechatLeaveList";
|
||||
String string2 = httpPost(method2, jsonStr2);
|
||||
List<EvectionBean> webchatList = FastJsonHelper.jsonArrStrToBeanList(string2, EvectionBean.class);
|
||||
syncLeaveToDatabase(webList,webchatList);
|
||||
log.info("--------休假出差数据定时器完毕------");
|
||||
}
|
||||
|
||||
private void syncLeaveToDatabase(List<EvectionBean> list, List<EvectionBean> wechatList) {
|
||||
// 将 wechatList 转换为 Map,以便快速查找
|
||||
Map<Long, EvectionBean> wechatUserMap = wechatList.stream()
|
||||
.collect(Collectors.toMap(EvectionBean::getId, user -> user, (existing, replacement) -> existing));
|
||||
// 遍历 list,检查每个用户是否存在于 wechatList 中
|
||||
for (EvectionBean bean : list) {
|
||||
Long id = bean.getId();
|
||||
if (!wechatUserMap.containsKey(id)) {
|
||||
// 如果 userId 不存在于 wechatList,则插入到数据库 a
|
||||
bean.setUuid(UUID.randomUUID().toString());
|
||||
String jsonStr2 = FastJsonHelper.beanToJsonStr(bean);
|
||||
String method2 = "insertWechatLeave";
|
||||
String string2 = httpPost(method2, jsonStr2);
|
||||
log.info("插入请假数据到小程序:"+string2);
|
||||
} else {
|
||||
// 如果存在,则判断时间是否后于小程序时间
|
||||
// 如果 userId 存在于 wechatList,则比较 updateTime
|
||||
EvectionBean wechatUser = wechatUserMap.get(id);
|
||||
if (bean.getUpdateTime().after(wechatUser.getUpdateTime())) {
|
||||
// 如果 list 中的 updateTime 更新,则更新数据库 a
|
||||
// dao.updateWechatPerson(user);
|
||||
String jsonStr = FastJsonHelper.beanToJsonStr(bean);
|
||||
String method = "updateWechatLeaveMsg";
|
||||
String string = httpPost(method, jsonStr);
|
||||
log.info("插入请假数据到小程序:" + string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Resource
|
||||
private AttTasks attTasks;
|
||||
|
||||
/**
|
||||
* 考勤数据同步定时器
|
||||
*/
|
||||
@Scheduled(initialDelay = 1000 * 18,fixedDelay = 60000 * 10)
|
||||
// @Scheduled(fixedDelay = 60000 * 10)
|
||||
@Async
|
||||
public void wechatAttTask() {
|
||||
log.info("--------考勤数据定时器开启------");
|
||||
|
|
@ -162,8 +194,14 @@ public class WechatTasks {
|
|||
// 如果Map中没有该userId的组织机构信息,则从数据库查询
|
||||
SysOrg orgInfo = dao.getOrgInfoByUserName(userName);
|
||||
if (orgInfo != null) {
|
||||
double distanceMeters = calculateDistance(bean.getAttLat(), bean.getAttLon(), orgInfo.getLat().longValue(), orgInfo.getLon().longValue(), DistanceCalculator.Unit.METERS);
|
||||
if (distanceMeters > orgInfo.getAttRange()) {
|
||||
double distanceMeters = 0;
|
||||
try {
|
||||
distanceMeters = calculateDistance(bean.getAttLat(), bean.getAttLon(), orgInfo.getLat().doubleValue(), orgInfo.getLon().doubleValue(), DistanceCalculator.Unit.METERS);
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
distanceMeters = 1000000;
|
||||
}
|
||||
if (distanceMeters > orgInfo.getAttRange()) {
|
||||
//外勤
|
||||
bean.setIsOutsideAtt("1");
|
||||
} else {
|
||||
|
|
@ -214,6 +252,7 @@ public class WechatTasks {
|
|||
// 将 wechatList 转换为 Map,以便快速查找
|
||||
Map<Long, SysUser> wechatUserMap = wechatList.stream()
|
||||
.collect(Collectors.toMap(SysUser::getUserId, user -> user, (existing, replacement) -> existing));
|
||||
|
||||
// 遍历 list,检查每个用户是否存在于 wechatList 中
|
||||
for (SysUser user : list) {
|
||||
Long userId = user.getUserId();
|
||||
|
|
@ -252,33 +291,37 @@ public class WechatTasks {
|
|||
String string = httpPost(method, jsonStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建一个包含list中所有用户ID的集合
|
||||
Set<Long> userIdsInList = list.stream()
|
||||
.map(SysUser::getUserId)
|
||||
.collect(Collectors.toSet());
|
||||
// 遍历 wechatUserMap,检查每个用户是否存在于 list 中
|
||||
for (Long wechatUserId : wechatUserMap.keySet()) {
|
||||
if (!userIdsInList.contains(wechatUserId)) {
|
||||
// 如果 userId 不存在于 list,则从数据库 a 删除
|
||||
SysUser wechatUser = wechatUserMap.get(wechatUserId);
|
||||
// 执行删除操作
|
||||
// dao.deleteWechatPerson(wechatUser);
|
||||
String jsonStr = FastJsonHelper.beanToJsonStr(wechatUser);
|
||||
String method = "deleteWechatPerson";
|
||||
String string = httpPost(method, jsonStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 休假出差数据同步定时器
|
||||
*/
|
||||
// @Scheduled(cron = "0 0/10 * * * ?")
|
||||
@Scheduled(initialDelay = 10000,fixedDelay = 60000 * 10)
|
||||
@Async
|
||||
public void getAttTasks() {
|
||||
log.info("--------休假出差数据同步定时器开启------");
|
||||
String today = DateUtil.today();
|
||||
log.info("--------休假出差数据同步定时器完毕------");
|
||||
}
|
||||
|
||||
|
||||
//人脸更新是调用的方法
|
||||
|
||||
|
||||
private String httpPost(String method, String jsonStr) {
|
||||
try {
|
||||
HttpResponse response = HttpRequest.post(IpAndPathConfig.getWechatUrl() + "/" + method)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(jsonStr)
|
||||
.execute();
|
||||
// HttpResponse response = HttpRequest.post(IpAndPathConfig.getWechatUrl() + "/" + method)
|
||||
// .header("Content-Type", "application/json")
|
||||
// .header("Authorization",token) // 添加Token到请求头
|
||||
// .body(jsonStr)
|
||||
// .execute();
|
||||
int statusCode = response.getStatus();
|
||||
JSONObject jsonObject = FastJsonHelper.jsonStrToJsonObj(response.body());
|
||||
return jsonObject.getString("obj");
|
||||
|
|
|
|||
|
|
@ -34,7 +34,28 @@ public class DistanceCalculator {
|
|||
* @param unit 距离单位(公里、英里或米)
|
||||
* @return 两点之间的距离
|
||||
*/
|
||||
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2, Unit unit) {
|
||||
/**
|
||||
* 计算两个地理坐标之间的距离。
|
||||
*
|
||||
* @param lat1 第一个坐标的纬度
|
||||
* @param lon1 第一个坐标的经度
|
||||
* @param lat2 第二个坐标的纬度
|
||||
* @param lon2 第二个坐标的经度
|
||||
* @param unit 距离单位(KILOMETERS, MILES, METERS)
|
||||
* @return 两个坐标之间的距离,如果输入无效则返回 1000000
|
||||
*/
|
||||
public static double calculateDistance(Double lat1, Double lon1, Double lat2, Double lon2, Unit unit) {
|
||||
// 检查输入是否为空
|
||||
if (lat1 == null || lon1 == null || lat2 == null || lon2 == null) {
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
// 检查纬度和经度是否在合理范围内
|
||||
if (!isValidLatitude(lat1) || !isValidLongitude(lon1) ||
|
||||
!isValidLatitude(lat2) || !isValidLongitude(lon2)) {
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
// 将纬度和经度从度转换为弧度
|
||||
double lat1Rad = Math.toRadians(lat1);
|
||||
double lon1Rad = Math.toRadians(lon1);
|
||||
|
|
@ -67,6 +88,26 @@ public class DistanceCalculator {
|
|||
return distance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查纬度是否在 -90 到 90 之间。
|
||||
*
|
||||
* @param lat 纬度
|
||||
* @return 如果纬度有效返回 true,否则返回 false
|
||||
*/
|
||||
private static boolean isValidLatitude(double lat) {
|
||||
return lat >= -90 && lat <= 90;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查经度是否在 -180 到 180 之间。
|
||||
*
|
||||
* @param lon 经度
|
||||
* @return 如果经度有效返回 true,否则返回 false
|
||||
*/
|
||||
private static boolean isValidLongitude(double lon) {
|
||||
return lon >= -180 && lon <= 180;
|
||||
}
|
||||
|
||||
/**
|
||||
* 距离单位枚举
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@
|
|||
= #{pushDate}
|
||||
</if>
|
||||
and g.id is not null
|
||||
and asd.data_source = 2
|
||||
and asd.data_source in (2,3)
|
||||
and (asd.att_type = 1
|
||||
or asd.att_type = 2);
|
||||
</select>
|
||||
|
|
|
|||
Loading…
Reference in New Issue