Bläddra i källkod

feat(pearl): 每日定时生成互动提醒任务

Sisyphus Agent 1 månad sedan
förälder
incheckning
8e67505cec

+ 88 - 0
cfc-backend/src/main/java/com/etotem/cfc/task/PearlReminderScheduledTask.java

@@ -0,0 +1,88 @@
+package com.etotem.cfc.task;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.entity.PearlInteractionReminder;
+import com.etotem.cfc.entity.ResourceItem;
+import com.etotem.cfc.enums.ConnectionType;
+import com.etotem.cfc.mapper.PearlInteractionReminderMapper;
+import com.etotem.cfc.mapper.ResourceItemMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Component
+public class PearlReminderScheduledTask {
+
+    @Resource
+    private ResourceItemMapper resourceItemMapper;
+
+    @Resource
+    private PearlInteractionReminderMapper reminderMapper;
+
+    /** 每日 08:00 生成珍珠图互动提醒 */
+    @Scheduled(cron = "0 0 8 * * ?")
+    public void generateReminders() {
+        log.info("===== PearlReminderScheduledTask 开始执行 =====");
+        try {
+            // 遍历所有带 connection_type 的资源
+            List<ResourceItem> items = resourceItemMapper.selectList(
+                    new LambdaQueryWrapper<ResourceItem>()
+                            .isNotNull(ResourceItem::getConnectionType)
+                            .ne(ResourceItem::getConnectionType, "")
+            );
+            int created = 0;
+            for (ResourceItem item : items) {
+                if (!ConnectionType.isValid(item.getConnectionType())) continue;
+                ConnectionType ct = null;
+                for (ConnectionType t : ConnectionType.values()) {
+                    if (t.name().equals(item.getConnectionType())) { ct = t; break; }
+                }
+                if (ct == null) continue;
+
+                int intervalDays = ct.getSuggestIntervalMonth() * 30;
+                long daysSinceLast;
+                if (item.getLastInteractionAt() == null) {
+                    // 从未互动:按创建时间起算
+                    Date base = item.getCreatedAt() != null ? item.getCreatedAt() : new Date();
+                    daysSinceLast = ChronoUnit.DAYS.between(base.toInstant(), Instant.now());
+                } else {
+                    daysSinceLast = ChronoUnit.DAYS.between(item.getLastInteractionAt().toInstant(), Instant.now());
+                }
+                if (daysSinceLast < intervalDays) continue; // 未到期
+
+                // 检查是否已有 PENDING 提醒
+                Long pendingCount = reminderMapper.selectCount(
+                        new LambdaQueryWrapper<PearlInteractionReminder>()
+                                .eq(PearlInteractionReminder::getUserId, item.getUserId())
+                                .eq(PearlInteractionReminder::getResourceItemId, item.getId())
+                                .eq(PearlInteractionReminder::getStatus, "PENDING")
+                );
+                if (pendingCount != null && pendingCount > 0) continue;
+
+                PearlInteractionReminder r = new PearlInteractionReminder();
+                r.setUserId(item.getUserId());
+                r.setResourceItemId(item.getId());
+                r.setConnectionType(item.getConnectionType());
+                r.setSuggestIntervalMonth(ct.getSuggestIntervalMonth());
+                r.setLastInteractionAt(item.getLastInteractionAt());
+                r.setDaysSinceLast((int) Math.max(0, daysSinceLast));
+                r.setStatus("PENDING");
+                r.setCreatedAt(new Date());
+                r.setUpdatedAt(new Date());
+                reminderMapper.insert(r);
+                created++;
+            }
+            log.info("珍珠图提醒生成完成,新增 {} 条", created);
+        } catch (Exception e) {
+            log.error("珍珠图提醒生成失败", e);
+        }
+        log.info("===== PearlReminderScheduledTask 执行完成 =====");
+    }
+}