diff --git a/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseTask.java b/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseTask.java index a5b8d8c0..9b8de218 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseTask.java +++ b/servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseTask.java @@ -18,6 +18,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; /** * @author by lyc @@ -37,8 +38,8 @@ public class StudyCourseTask { * 定时任务 * 获取redis 中学习结束的数据更新入库 * */ - @XxlJob("saveStudyCourseItemLastTime") - public void saveStudyCourseItemLastTime() { + @XxlJob("saveStudyCourseItemLastTime2") + public void saveStudyCourseItemLastTime2() { // 1. 定义匹配模式(匹配所有目标key) final String KEY_PATTERN = "studyContentId:*:last_active"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); @@ -161,4 +162,90 @@ public class StudyCourseTask { } + + @XxlJob("saveStudyCourseItemLastTime") + public void saveStudyCourseItemLastTime() { + // 定义需要处理的键模式集合 + processKeys("studyContentId:*:last_active", this::handleLastActiveKey); + processKeys("studyId:*:courseId:*:courseContentId:*", this::handleDurationKey); + } + + private void processKeys(String keyPattern, BiConsumer keyHandler) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + ScanOptions options = ScanOptions.scanOptions() + .match(keyPattern) + .count(100) + .build(); + + try (RedisConnection connection = Objects.requireNonNull(redisTemplate.getConnectionFactory()).getConnection()) { + Cursor cursor = connection.scan(options); + while (cursor.hasNext()) { + String redisKey = new String(cursor.next()); + Long ttl = redisTemplate.getExpire(redisKey, TimeUnit.SECONDS); + + if (ttl != null && ttl <= 2590200) { + try { + String redisValue = redisTemplate.opsForValue().get(redisKey); + if (redisValue != null) { + // 调用对应的处理方法 + keyHandler.accept(redisKey, redisValue); + } + redisTemplate.delete(redisKey); + log.info("Key processed: {}", redisKey); + } catch (Exception e) { + log.error("Process failed [{}]", redisKey, e); + } + } + } + cursor.close(); + } catch (Exception e) { + log.error("Key processing error: {}", keyPattern, e); + } + } + + // 处理 last_active 类型键 + private void handleLastActiveKey(String redisKey, String redisValue) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + String[] parts = redisKey.split(":"); + String studyContentId = parts[1]; + + String[] values = redisValue.split("&"); + int lastStudyTime = Integer.parseInt(values[0]); + LocalDateTime timestamp = values.length >= 2 ? + LocalDateTime.parse(values[1], formatter) : null; + + studyService.updateStudyCourseItemLastTime(studyContentId, lastStudyTime, timestamp); + } + + // 处理 duration 类型键 + private void handleDurationKey(String redisKey, String redisValue) { + String[] parts = redisKey.split(":"); + String studyId = parts[1]; + String courseId = parts[3]; + String courseContentId = parts[5]; + + String[] values = redisValue.split("&"); + int duration = Integer.parseInt(values[0]); + LocalDateTime timestamp = values.length >= 2 ? + LocalDateTime.parse(values[1], DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null; + + studyService.newAppendStudyDuration(studyId, null, courseContentId, duration, timestamp); + + // 保留第三方调用 + List allUserList = thirdApi.getStudyCourseList(studyId, courseId, null); + log.info("Study records synced: {}", allUserList.size()); + } + + + + + + + + + + + + + }