|
|
@@ -202,6 +202,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
private DepartmentMapper departmentMapper;
|
|
|
@Autowired
|
|
|
private UserCorpwxTimeService userCorpwxTimeService;
|
|
|
+ @Autowired
|
|
|
+ private ExceptionInfosService exceptionInfosService;
|
|
|
|
|
|
|
|
|
//获取服务商provider_access_token
|
|
|
@@ -732,12 +734,18 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
System.out.println("获取企微考勤 startTime=" + startTime + ",endTime=" + endTime);
|
|
|
|
|
|
int batchCount = 1;
|
|
|
- int batchSize = 1;
|
|
|
+ int batchSize = 100;
|
|
|
int totalLength = 1;
|
|
|
List<String> corpwxUserIds = new ArrayList<>();
|
|
|
if (userId == null) {
|
|
|
//获取企业下的全部员工
|
|
|
- List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).isNotNull("corpwx_userid").eq("is_active", 1).eq("report_status", 0));
|
|
|
+ QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("company_id", companyId).isNotNull("corpwx_userid").eq("is_active", 1);
|
|
|
+ if (!(companyId == Constant.XI_HE_CHAO_DAO_COMPANY_ID || companyId == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID)) {
|
|
|
+ queryWrapper.eq("report_status", 0);//只取需要提醒填报的人员
|
|
|
+ }
|
|
|
+// queryWrapper.eq("report_status", 1);
|
|
|
+ List<User> users = userMapper.selectList(queryWrapper);
|
|
|
+
|
|
|
System.out.println("获取考勤记录users size==" + users.size()+", companyId="+companyId+", "+corpInfo.getCorpName());
|
|
|
corpwxUserIds = users.stream().map(User::getCorpwxUserid).collect(Collectors.toList());
|
|
|
totalLength = corpwxUserIds.size();
|
|
|
@@ -770,7 +778,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public HttpRespMsg getUserPunchRecord(int companyId, String userId, LocalDateTime startDateTime, LocalDateTime endDateTime, boolean showLog) {
|
|
|
+ public HttpRespMsg getUserPunchRecord(int companyId, String corpwxUserid, LocalDateTime startDateTime, LocalDateTime endDateTime, boolean showLog) {
|
|
|
HttpRespMsg msg = new HttpRespMsg();
|
|
|
WxCorpInfo corpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
|
|
|
if (corpInfo == null) {
|
|
|
@@ -793,7 +801,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
int batchSize = 100;
|
|
|
int totalLength = 1;
|
|
|
List<String> corpwxUserIds = new ArrayList<>();
|
|
|
- if (userId == null) {
|
|
|
+ if (corpwxUserid == null) {
|
|
|
//获取企业下的全部员工
|
|
|
List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).isNotNull("corpwx_userid").eq("is_active", 1));
|
|
|
corpwxUserIds = users.stream().map(User::getCorpwxUserid).collect(Collectors.toList());
|
|
|
@@ -801,8 +809,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
batchCount = totalLength / batchSize + (totalLength % batchSize == 0 ? 0 : 1);
|
|
|
} else {
|
|
|
//指定获取员工
|
|
|
- User user = userMapper.selectById(userId);
|
|
|
- corpwxUserIds.add(user.getCorpwxUserid());
|
|
|
+// User user = userMapper.selectById(userId);
|
|
|
+ corpwxUserIds.add(corpwxUserid);
|
|
|
}
|
|
|
//按批调用
|
|
|
for (int i = 0; i < batchCount; i++) {
|
|
|
@@ -1067,7 +1075,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
String checkinOption = getCheckinOption(corpInfo, dataTime, objects);
|
|
|
JSONObject optionObject = JSONObject.parseObject(checkinOption);
|
|
|
// showLog = true;
|
|
|
- JSONArray optionDatas= optionObject.getJSONArray("info");
|
|
|
+ JSONArray optionDatas = optionObject.getJSONArray("info");
|
|
|
String url = GET_CHECKIN_DATA.replace("ACCESS_TOKEN", getCorpAccessToken(corpInfo));
|
|
|
HttpHeaders headers = new HttpHeaders();
|
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
@@ -1285,12 +1293,19 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
//遍历,计算加班时长
|
|
|
List<UserCorpwxTime> updateList = new ArrayList<>();
|
|
|
for (UserCorpwxTime time : userCorpwxTimes) {
|
|
|
- double overtime = DateTimeUtil.calculateOvertime(time.getStartTime(), time.getEndTime());
|
|
|
+ double overtime = DateTimeUtil.calculateOvertime(time.getCreateDate(), time.getStartTime(), time.getEndTime());
|
|
|
if (overtime > 0) {
|
|
|
UserCorpwxTime copy = new UserCorpwxTime();
|
|
|
copy.setId(time.getId());
|
|
|
copy.setOtTime(overtime);
|
|
|
- copy.setOtStatus(1);
|
|
|
+ if (time.getWorkHours() == 0) {
|
|
|
+ //工作时长为0,但是计算的加班时长是有的,说明当天是请假了全天,之前有的加班时长需要更新为0
|
|
|
+ copy.setOtTime(0.0);
|
|
|
+ copy.setOtStatus(null);
|
|
|
+ } else {
|
|
|
+ copy.setOtTime(overtime);
|
|
|
+ copy.setOtStatus(1);
|
|
|
+ }
|
|
|
updateList.add(copy);
|
|
|
}
|
|
|
}
|
|
|
@@ -1572,6 +1587,20 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
if (json.getIntValue("errcode") == 0) {
|
|
|
JSONArray datas = json.getJSONArray("datas");
|
|
|
+ List<ExceptionInfos> allExceptionInfoList = new ArrayList<>();
|
|
|
+ //将startTime转化为LocalDate, startTime是秒为单位的。
|
|
|
+ LocalDate startLocalDate = Instant.ofEpochSecond(startTime).atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ LocalDate endLocalDate = Instant.ofEpochSecond(endTime).atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ if (corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID || corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID) {
|
|
|
+ //先删除日期范围内的人员的所有异常记录
|
|
|
+ exceptionInfosMapper.delete(new QueryWrapper<ExceptionInfos>().eq("company_id", corpInfo.getCompanyId()).between("create_date", startLocalDate, endLocalDate).in("corpwx_userid", Arrays.asList(objects)));
|
|
|
+ }
|
|
|
+ //统一查询已有数据记录
|
|
|
+ List<UserCorpwxTime> allExistingCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>()
|
|
|
+ .eq("company_id", corpInfo.getCompanyId()).between("create_date", startLocalDate, endLocalDate).in("corpwx_userid", Arrays.asList(objects)));
|
|
|
+
|
|
|
+ List<UserCorpwxTime> updateList = new ArrayList<>();
|
|
|
+ List<UserCorpwxTime> insertList = new ArrayList<>();
|
|
|
for (int i = 0; i < datas.size(); i++) {
|
|
|
JSONObject jsonObject = datas.getJSONObject(i);
|
|
|
JSONObject base_info = jsonObject.getJSONObject("base_info");
|
|
|
@@ -1638,6 +1667,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
UserCorpwxTime ct = new UserCorpwxTime();
|
|
|
ct.setCompanyId(corpInfo.getCompanyId());
|
|
|
ct.setCorpwxUserid(curUserid);
|
|
|
+ ct.setName(name);
|
|
|
ct.setWxCorpid(corpInfo.getCorpid());
|
|
|
ct.setCreateDate(localDate);
|
|
|
//计算周几
|
|
|
@@ -1665,7 +1695,6 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
ct.setOutdoorTime(0.0);
|
|
|
if (isCrossDay) {
|
|
|
//直接用cardTime作为工作时长
|
|
|
- ct.setName(name);
|
|
|
ct.setWorkHours(DateTimeUtil.getHoursFromDouble(ct.getCardTime()));
|
|
|
}
|
|
|
//工作日或者非工作日有打卡/加班,需要校正请假,外出的时长数据
|
|
|
@@ -1966,7 +1995,6 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
timeDelta = ct.getCardTime();
|
|
|
}
|
|
|
}
|
|
|
- ct.setName(name);
|
|
|
//解析请假和外出的情况
|
|
|
JSONArray sp_items = jsonObject.getJSONArray("sp_items");
|
|
|
for (int j = 0; j < sp_items.size(); j++) {
|
|
|
@@ -2222,8 +2250,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- List<UserCorpwxTime> itemList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", curUserid)
|
|
|
- .eq("create_date", localDate));
|
|
|
+ List<UserCorpwxTime> itemList = allExistingCorpwxTimeList.stream().filter(t -> t.getCorpwxUserid().equals(curUserid) && t.getCreateDate().equals(localDate)).collect(Collectors.toList());
|
|
|
//有工作时长或者打卡时长或者请假时长,外出时长,都算有效时间
|
|
|
boolean hasTimeRecord = ct.getWorkHours() > 0 || ct.getCardTime() >= 1.0 || ct.getAskLeaveTime() > 0 || ct.getOutdoorTime() > 0;
|
|
|
//对于赛元微电子,2025年4月1日之前的都不做处理,防止把数据覆盖掉
|
|
|
@@ -2234,40 +2261,48 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
if (itemList.size() > 0) {
|
|
|
UserCorpwxTime item = itemList.get(0);
|
|
|
if (item.getModifiedByAdmin() != null && item.getModifiedByAdmin() == 0) {//自动同步的数据可以更新,管理员手动修改的不能覆盖掉
|
|
|
- if (itemList.size() > 1) {
|
|
|
- System.out.println("数据异常: "+curUserid+", "+localDate+". 存在"+itemList.size()+"条考勤,已自动删除多余的");
|
|
|
- for (int t=1; t < itemList.size(); t++) {
|
|
|
- userCorpwxTimeMapper.deleteById(itemList.get(t).getId());
|
|
|
- }
|
|
|
- }
|
|
|
ct.setId(item.getId());
|
|
|
//之前有的时长不合法,或者新的有打卡时长
|
|
|
if (item.getWorkHours() <= 0 || hasTimeRecord) {
|
|
|
if (showLog) System.out.println("更新考勤记录"+curUserid+", "+localDate);
|
|
|
- userCorpwxTimeMapper.updateById(ct);
|
|
|
+// userCorpwxTimeMapper.updateById(ct);
|
|
|
+ updateList.add(ct);
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
if (hasTimeRecord) {
|
|
|
if (showLog) System.out.println("插入考勤记录"+curUserid+", "+localDate);
|
|
|
- userCorpwxTimeMapper.insert(ct);
|
|
|
-
|
|
|
- } else {
|
|
|
- //调用打卡详情去获取,弥补外出打卡且时间不在自动同步范围内的情况; 仅对工作日有效
|
|
|
- if (timeTypeService.isWorkDay(corpInfo.getCompanyId(), localDate, timeType, holidaySettings)) {
|
|
|
- User user = userMapper.selectOne(new QueryWrapper<User>().eq("corpwx_userid", curUserid));
|
|
|
- if (user != null) {
|
|
|
- getUserPunchRecord(corpInfo.getCompanyId(), user.getId(), localDate.atTime(0,0,0),
|
|
|
- localDate.atTime(23,59,59), showLog);
|
|
|
- }
|
|
|
- }
|
|
|
+// userCorpwxTimeMapper.insert(ct);
|
|
|
+ insertList.add(ct);
|
|
|
}
|
|
|
+ //影响性能,此处不再获取打卡,用户手动刷新单日接口本身有后续的获取打卡记录步骤,这里为冗余代码,需要去掉
|
|
|
+// else if (startTime == endTime){ //只在单日刷新考勤的情况下,才去获取打卡详情来计算
|
|
|
+// //调用打卡详情去获取,弥补外出打卡且时间不在自动同步范围内的情况; 仅对工作日有效
|
|
|
+// if (timeTypeService.isWorkDay(corpInfo.getCompanyId(), localDate, timeType, holidaySettings)) {
|
|
|
+// getUserPunchRecord(corpInfo.getCompanyId(), curUserid, localDate.atTime(0,0,0),
|
|
|
+// localDate.atTime(23,59,59), showLog);
|
|
|
+// }
|
|
|
+// }
|
|
|
}
|
|
|
//保存异常情况记录
|
|
|
if (corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID || corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID) {
|
|
|
- saveException(ct, jsonObject.getJSONArray("exception_infos"));
|
|
|
+// saveException(ct, jsonObject.getJSONArray("exception_infos"));
|
|
|
+ List<ExceptionInfos> exceptionInfos = getExceptionInfos(ct, jsonObject.getJSONArray("exception_infos"));
|
|
|
+ if (exceptionInfos != null) {
|
|
|
+ allExceptionInfoList.addAll(exceptionInfos);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ //批量操作,效率高
|
|
|
+ if (!updateList.isEmpty()) {
|
|
|
+ userCorpwxTimeService.updateBatchById(updateList);
|
|
|
+ }
|
|
|
+ if (!insertList.isEmpty()) {
|
|
|
+ userCorpwxTimeService.saveBatch(insertList);
|
|
|
+ }
|
|
|
+ if (!allExceptionInfoList.isEmpty()) {
|
|
|
+ exceptionInfosService.saveBatch(allExceptionInfoList);
|
|
|
+ }
|
|
|
} else {
|
|
|
//TODO: 记录同步失败
|
|
|
|
|
|
@@ -2277,23 +2312,22 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void saveException(UserCorpwxTime userCorpwxTime,JSONArray exceptionInfos) {
|
|
|
- //删除当日的异常
|
|
|
- exceptionInfosMapper.delete(new QueryWrapper<ExceptionInfos>().eq("create_date", userCorpwxTime.getCreateDate()).eq("corpwx_userid", userCorpwxTime.getCorpwxUserid()).eq("company_id", userCorpwxTime.getCompanyId()));
|
|
|
+ private List<ExceptionInfos> getExceptionInfos(UserCorpwxTime userCorpwxTime,JSONArray exceptionInfos) {
|
|
|
+ List<ExceptionInfos> list = null;
|
|
|
if (exceptionInfos != null && exceptionInfos.size() > 0) {
|
|
|
//重新保存
|
|
|
+ list = new ArrayList<>();
|
|
|
for (int i = 0; i < exceptionInfos.size(); i++) {
|
|
|
ExceptionInfos exceptionInfos1 = exceptionInfos.getObject(i, ExceptionInfos.class);
|
|
|
- exceptionInfos1.setCorpwxtimeId(userCorpwxTime.getId());
|
|
|
exceptionInfos1.setCreateDate(userCorpwxTime.getCreateDate());
|
|
|
exceptionInfos1.setCorpwxUserid(userCorpwxTime.getCorpwxUserid());
|
|
|
exceptionInfos1.setCompanyId(userCorpwxTime.getCompanyId());
|
|
|
- exceptionInfosMapper.insert(exceptionInfos1);
|
|
|
+ list.add(exceptionInfos1);
|
|
|
}
|
|
|
}
|
|
|
+ return list;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private double convertDayTimeToHours(double d) {
|
|
|
if (d == 12) {
|
|
|
return 4.0;
|