| | |
| | | private Integer timelineId; |
| | | private String deviceid; |
| | | } |
| | | |
| | | // ==================== 设备打卡数据结构 ==================== |
| | | |
| | | @Data |
| | | private static class WorkWXHardwareCheckinResponse { |
| | | private Integer errcode; |
| | | private String errmsg; |
| | | private List<HardwareCheckinData> checkindata; |
| | | } |
| | | |
| | | @Data |
| | | public static class HardwareCheckinData { |
| | | private String userid; |
| | | @JsonProperty("checkin_time") |
| | | private Long checkinTime; |
| | | @JsonProperty("device_sn") |
| | | private String deviceSn; |
| | | @JsonProperty("device_name") |
| | | private String deviceName; |
| | | } |
| | | |
| | | /** |
| | | * 获取设备打卡数据 |
| | | * 接口文档: https://developer.work.weixin.qq.com/document/path/94126 |
| | | * 1. 获取记录时间跨度不超过一个月 |
| | | * 2. 用户列表不超过100个,若用户超过100个,请分批获取 |
| | | * |
| | | * @param startTime 开始时间戳(秒) |
| | | * @param endTime 结束时间戳(秒) |
| | | * @param useridList 用户ID列表 |
| | | * @return 设备打卡数据列表 |
| | | */ |
| | | public List<HardwareCheckinData> getHardwareCheckinData(long startTime, long endTime, List<String> useridList) throws IOException { |
| | | String accessToken = getAccessToken(); |
| | | String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/hardware/get_hardware_checkin_data?access_token=%s", accessToken); |
| | | |
| | | List<HardwareCheckinData> allCheckinData = new ArrayList<>(); |
| | | |
| | | int batchSize = 100; |
| | | int totalUsers = useridList.size(); |
| | | int batchCount = (totalUsers + batchSize - 1) / batchSize; |
| | | |
| | | log.info("开始获取设备打卡数据,总用户数: {}, 分批数: {}, 时间范围: {} - {}", totalUsers, batchCount, startTime, endTime); |
| | | |
| | | for (int i = 0; i < batchCount; i++) { |
| | | int fromIndex = i * batchSize; |
| | | int toIndex = Math.min((i + 1) * batchSize, totalUsers); |
| | | |
| | | List<String> batchUserList = useridList.subList(fromIndex, toIndex); |
| | | log.info("正在获取第 {}/{} 批设备打卡数据,用户数: {}", i + 1, batchCount, batchUserList.size()); |
| | | |
| | | Map<String, Object> requestBody = new HashMap<>(); |
| | | requestBody.put("filter_type", 1); // 1表示按userid过滤 |
| | | requestBody.put("starttime", startTime); |
| | | requestBody.put("endtime", endTime); |
| | | requestBody.put("useridlist", batchUserList); |
| | | |
| | | MediaType mediaType = MediaType.parse("application/json; charset=UTF-8"); |
| | | String jsonBody = objectMapper.writeValueAsString(requestBody); |
| | | RequestBody body = RequestBody.create(mediaType, jsonBody); |
| | | |
| | | Request request = new Request.Builder() |
| | | .url(url) |
| | | .post(body) |
| | | .addHeader("Content-Type", "application/json; charset=UTF-8") |
| | | .build(); |
| | | |
| | | try (Response response = client.newCall(request).execute()) { |
| | | if (!response.isSuccessful()) { |
| | | log.error("获取设备打卡数据失败,HTTP状态码: {}", response.code()); |
| | | throw new IOException("获取设备打卡数据失败: " + response.message()); |
| | | } |
| | | |
| | | String responseBody = response.body().string(); |
| | | |
| | | WorkWXHardwareCheckinResponse checkinResponse = objectMapper.readValue(responseBody, WorkWXHardwareCheckinResponse.class); |
| | | |
| | | if (checkinResponse.getErrcode() != 0) { |
| | | log.error("获取设备打卡数据失败,错误码: {}, 错误信息: {}", |
| | | checkinResponse.getErrcode(), checkinResponse.getErrmsg()); |
| | | throw new IOException("获取设备打卡数据失败: " + checkinResponse.getErrmsg()); |
| | | } |
| | | |
| | | if (checkinResponse.getCheckindata() != null) { |
| | | allCheckinData.addAll(checkinResponse.getCheckindata()); |
| | | log.info("第 {}/{} 批获取到设备打卡记录数: {}", i + 1, batchCount, checkinResponse.getCheckindata().size()); |
| | | } |
| | | } |
| | | |
| | | // 批次间等待500ms,避免请求过于频繁 |
| | | if (i < batchCount - 1) { |
| | | try { |
| | | Thread.sleep(500); |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.warn("批次间等待被中断"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | log.info("设备打卡数据获取完成,总记录数: {}", allCheckinData.size()); |
| | | return allCheckinData; |
| | | } |
| | | |
| | | /** |
| | | * 根据QW_STAFF表获取设备打卡数据 |
| | | * |
| | | * @param startTime 开始时间戳(秒) |
| | | * @param endTime 结束时间戳(秒) |
| | | * @return 设备打卡数据列表 |
| | | */ |
| | | public List<HardwareCheckinData> getHardwareCheckinDataByQwStaff(long startTime, long endTime) throws IOException { |
| | | List<QwStaff> qwStaffList = qwStaffMapper.selectList(new LambdaQueryWrapper<QwStaff>()); |
| | | |
| | | if (qwStaffList == null || qwStaffList.isEmpty()) { |
| | | log.warn("QW_STAFF表中没有数据"); |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | List<String> useridList = qwStaffList.stream() |
| | | .map(QwStaff::getAccount) |
| | | .filter(account -> account != null && !account.isEmpty()) |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (useridList.isEmpty()) { |
| | | log.warn("QW_STAFF表中没有有效的account数据"); |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | log.info("从QW_STAFF表获取到 {} 个用户account", useridList.size()); |
| | | return getHardwareCheckinData(startTime, endTime, useridList); |
| | | } |
| | | } |