|
@@ -387,6 +387,10 @@ public class HKImplClient implements HKClient {
|
|
|
private void _syncCheckingRecord(boolean isIn, String time, String employeeId) {
|
|
|
String type = isIn ? "ClockIn" : "ClockOut";
|
|
|
String url = _getMonitorApi("/api/v1/TimeRecording/RecordingDays/" + type);
|
|
|
+ // 若不传递 TimeStamp, 则会以当前时间
|
|
|
+ if (StringUtils.isBlank(time)) {
|
|
|
+ time = UtilDateTime.formatDateTime(new Date());
|
|
|
+ }
|
|
|
Map param = UtilMap.map("EmployeeId, TimeStamp", employeeId, time);
|
|
|
okRequest(url, _getAuthSessionId(), param);
|
|
|
}
|
|
@@ -407,7 +411,7 @@ public class HKImplClient implements HKClient {
|
|
|
private Map<String, Boolean> checkStatus = new HashMap();
|
|
|
|
|
|
/**
|
|
|
- * prd monitor clockIn, clockOut 必须成对出现, 且后一次时间必须在前一次时间之后, 否则均同步异常;
|
|
|
+ * prd monitor clockIn, clockOut 必须成对出现, 且后一次时间必须在前一次时间之后, 否则均同步异常; ppExt: prd 25-05-06 考勤方案修正为全量, 确保上下班正常
|
|
|
* [方案: in/out 若是同一个时间可以反复调用]
|
|
|
* 1. 钉钉已设置为严格打卡模式, 一次上班卡\一次下班卡, 成对出现, 不取值最早和最晚时间
|
|
|
* 2. 每天早上7点重置打卡标记状态, 避免通过标记第一次打卡就是 clock-out 情况, 导致后续与实际考勤一直异常
|
|
@@ -434,7 +438,7 @@ public class HKImplClient implements HKClient {
|
|
|
_syncCheckingRecord(isIn, timeStamp, employeeId);
|
|
|
} catch (Exception e) {
|
|
|
// fixme: 因 monitor 写入要求, 重复下班 expected Out got In 报错; 重复上班 expected In got Out 报错
|
|
|
- if (e.getMessage().contains("expected In got Out") || e.getMessage().contains("expected In got Out")) {
|
|
|
+ if (e.getMessage().contains("expected In got Out") || e.getMessage().contains("expected Out got In")) {
|
|
|
String tTime = UtilDateTime.formatDate(new Date(UtilMap.getLong(data, "checkTime") - 24 * 60 * 60 * 1000));
|
|
|
if (e.getMessage().contains("expected In got Out")) {
|
|
|
tTime = tTime + " 23:59:58";
|
|
@@ -470,7 +474,6 @@ public class HKImplClient implements HKClient {
|
|
|
userIds = syncContact(true);
|
|
|
}
|
|
|
List<Map> reflects = getUserIdReflect(); // 钉钉Id -> monitorId
|
|
|
-// List<Map> reflects = Arrays.asList(UtilMap.map("textField_m4sjp8pf, textField_m4sjp8pg", "131022580326061279, 1082858538248001906"));
|
|
|
log.info("考勤同步信息, 人员数量 = {}, id映射表数据 = {}", userIds.size(), reflects.size());
|
|
|
|
|
|
for (String userId : userIds) {
|
|
@@ -481,10 +484,27 @@ public class HKImplClient implements HKClient {
|
|
|
continue;
|
|
|
}
|
|
|
String employeeId = UtilMap.getString((Map) optional.get(), "textField_m4sjp8pg");
|
|
|
+ if (employeeId.contains("_")) {
|
|
|
+ employeeId = employeeId.split("_")[1];
|
|
|
+ }
|
|
|
Map record = ddClient_attendance.getAttendanceRecord(ddClient.getAccessToken(), userId, tDate);
|
|
|
List<Map> checks = UtilMap.getList(record, "attendance_result_list");
|
|
|
+ // 缺卡处理逻辑
|
|
|
+ if (checks.size() == 1) {
|
|
|
+ Map tmp = UtilMap.empty();
|
|
|
+ long tms = UtilDateTime.parseDateTime(UtilMap.getString(checks.get(0), "user_check_time")).getTime();
|
|
|
+ if ("OffDuty".equals(UtilMap.getString(checks.get(0), "check_type"))) {
|
|
|
+ tmp.put("check_type", "OnDuty");
|
|
|
+ tmp.put("user_check_time", UtilDateTime.formatDateTime(new Date(tms - 1000L)));
|
|
|
+ } else {
|
|
|
+ tmp.put("check_type", "OffDuty");
|
|
|
+ tmp.put("user_check_time", UtilDateTime.formatDateTime(new Date(tms + 1000L)));
|
|
|
+ }
|
|
|
+ checks.add(tmp);
|
|
|
+ }
|
|
|
checks.sort(Comparator.comparingLong(item -> UtilDateTime.parseDateTime(UtilMap.getString(item, "user_check_time")).getTime())); // 排序
|
|
|
log.info("考勤记录, {}, result = {}, record = {}", UtilMap.getString((Map) optional.get(), "employeeField_lo47byyj"), checks.size(), UtilMap.getList(record, "check_record_list").size());
|
|
|
+
|
|
|
for (Map check : checks) {
|
|
|
boolean isIn = !"OffDuty".equals(UtilMap.getString(check, "check_type"));
|
|
|
try {
|
|
@@ -508,5 +528,38 @@ public class HKImplClient implements HKClient {
|
|
|
.formDataJson(JSON.toJSONString(formData))
|
|
|
.build(), YDConf.FORM_OPERATION.create);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * prd 数据修正 2025-05-06
|
|
|
+ * - fixme: 存在钉钉考勤回调历史原因, 若已有当前时间打卡, 则之前时间数据无法写入. 更新当前生产环境所有人考勤下班时间为 17:00
|
|
|
+ * - ppExt: 若 报错为 Recording template is not valid: FutureRecordingsDetected, 则存在有记录已大于当前传递考勤时间
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void _correctionAttendance() {
|
|
|
+
|
|
|
+ List<String> userIds = syncContact(true);
|
|
|
+ List<Map> reflects = getUserIdReflect(); // 钉钉Id -> monitorId
|
|
|
+ log.info("考勤同步信息, 人员数量 = {}, id映射表数据 = {}", userIds.size(), reflects.size());
|
|
|
+
|
|
|
+ for (String userId : userIds) {
|
|
|
+ Optional optional = reflects.stream().filter(item -> userId.equals(UtilMap.getString(item, "textField_m4sjp8pf"))).findAny();
|
|
|
+ if (!optional.isPresent()) {
|
|
|
+ Map formData = UtilMap.map("dateField_lo47byyd, employeeField_lo47byyj, textareaField_lo47byyo, textareaField_lo47sanj", new Date().getTime(), userId, "monitor id 未匹配, 请管理员维护", "");
|
|
|
+ _attendanceExceptionRecord(formData);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String employeeId = UtilMap.getString((Map) optional.get(), "textField_m4sjp8pg");
|
|
|
+ if (employeeId.contains("_")) {
|
|
|
+ employeeId = employeeId.split("_")[1];
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ _syncCheckingRecord(false, "2025-05-06 17:00:00", employeeId);
|
|
|
+ } catch (McException e) {
|
|
|
+ if (!(e.getMessage().contains("expected In got Out") || e.getMessage().contains("expected Out got In"))) {
|
|
|
+ log.error(UtilMap.getString((Map) optional.get(), "employeeField_lo47byyj"), e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|