ソースを参照

feat(recommend): 同步 Manager(规则写库+POP/历史/指针 Manager,规则查询加batchNo)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jintao.geng 1 ヶ月 前
コミット
9aa37f9ca3

+ 20 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/ActiveBatchManager.java

@@ -0,0 +1,20 @@
+package com.mangoo.rating.recommend.manager;
+
+/**
+ * 生效批次指针 Manager(封装 Mapper,做空值校验)
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+public interface ActiveBatchManager {
+
+    /**
+     * 读取当前生效批次号(无则返回 null)
+     */
+    String selectActiveBatchNo();
+
+    /**
+     * 数仓同步:更新生效批次指针(单行指针表)
+     */
+    int updateActiveBatchNo(String batchNo);
+}

+ 29 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/CardPopManager.java

@@ -0,0 +1,29 @@
+package com.mangoo.rating.recommend.manager;
+
+import com.mangoo.rating.recommend.po.CardPopPO;
+
+import java.util.List;
+
+/**
+ * 卡片 POP 明细 Manager(封装 Mapper,做空值校验)
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+public interface CardPopManager {
+
+    /**
+     * 数仓同步:批量插入 POP 明细(物理全量替换)
+     */
+    int batchInsert(List<CardPopPO> list);
+
+    /**
+     * 数仓同步:按批次号物理删除 POP 明细(配合全量替换)
+     */
+    int deleteByBatchNo(String batchNo);
+
+    /**
+     * 按卡片ID + 批次查 POP 明细(三机构多行)
+     */
+    List<CardPopPO> selectByCardId(String cardId, String batchNo);
+}

+ 25 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/CardValueHistoryManager.java

@@ -0,0 +1,25 @@
+package com.mangoo.rating.recommend.manager;
+
+import com.mangoo.rating.recommend.po.CardValueHistoryPO;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * 卡片价格历史 Manager(封装 Mapper,做空值校验)
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+public interface CardValueHistoryManager {
+
+    /**
+     * 数仓同步:批量 UPSERT 价格历史(依赖唯一索引,冲突则更新价格)
+     */
+    int batchUpsert(List<CardValueHistoryPO> list);
+
+    /**
+     * 查某卡价格历史趋势;startDate 为 null 时查全部,否则查 record_date >= startDate
+     */
+    List<CardValueHistoryPO> selectTrend(String cardId, LocalDate startDate);
+}

+ 21 - 6
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/RatingRecommendRuleManager.java

@@ -11,17 +11,32 @@ import com.mangoo.rating.recommend.po.RatingRecommendRulePO;
 public interface RatingRecommendRuleManager {
 
     /**
-     * L1:四字段全等命中(任一为空则不查询,返回 null)
+     * L1:四字段全等命中(任一为空则不查询,返回 null;batchNo 限定生效批次,为空返回 null
      */
-    RatingRecommendRulePO selectByExact(String player, String year, String series, String cardSet);
+    RatingRecommendRulePO selectByExact(String player, String year, String series, String cardSet, String batchNo);
 
     /**
-     * L2:系列+卡种+年份命中(三个参与字段任一为空则不查询)
+     * L2:系列+卡种+年份命中(三个参与字段任一为空则不查询;batchNo 限定生效批次,为空返回 null
      */
-    RatingRecommendRulePO selectBySeriesSetYear(String series, String cardSet, String year);
+    RatingRecommendRulePO selectBySeriesSetYear(String series, String cardSet, String year, String batchNo);
 
     /**
-     * L3:系列+卡种命中(两个参与字段任一为空则不查询)
+     * L3:系列+卡种命中(两个参与字段任一为空则不查询;batchNo 限定生效批次,为空返回 null
      */
-    RatingRecommendRulePO selectBySeriesSet(String series, String cardSet);
+    RatingRecommendRulePO selectBySeriesSet(String series, String cardSet, String batchNo);
+
+    /**
+     * 数仓同步:批量插入规则(物理全量替换)
+     */
+    int batchInsert(java.util.List<com.mangoo.rating.recommend.po.RatingRecommendRulePO> list);
+
+    /**
+     * 数仓同步:按批次号物理删除规则(配合全量替换)
+     */
+    int deleteByBatchNo(String batchNo);
+
+    /**
+     * 数仓同步:查询所有去重批次号(用于清理过期批次)
+     */
+    java.util.List<String> selectDistinctBatchNos();
 }

+ 35 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/impl/ActiveBatchManagerImpl.java

@@ -0,0 +1,35 @@
+package com.mangoo.rating.recommend.manager.impl;
+
+import com.mangoo.rating.recommend.manager.ActiveBatchManager;
+import com.mangoo.rating.recommend.mapper.ActiveBatchMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 生效批次指针 Manager 实现
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+@Slf4j
+@Component
+public class ActiveBatchManagerImpl implements ActiveBatchManager {
+
+    @Resource
+    private ActiveBatchMapper activeBatchMapper;
+
+    @Override
+    public String selectActiveBatchNo() {
+        return activeBatchMapper.selectActiveBatchNo();
+    }
+
+    @Override
+    public int updateActiveBatchNo(String batchNo) {
+        if (batchNo == null || batchNo.trim().isEmpty()) {
+            return 0;
+        }
+        return activeBatchMapper.updateActiveBatchNo(batchNo);
+    }
+}

+ 51 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/impl/CardPopManagerImpl.java

@@ -0,0 +1,51 @@
+package com.mangoo.rating.recommend.manager.impl;
+
+import com.mangoo.rating.recommend.manager.CardPopManager;
+import com.mangoo.rating.recommend.mapper.CardPopMapper;
+import com.mangoo.rating.recommend.po.CardPopPO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 卡片 POP 明细 Manager 实现
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+@Slf4j
+@Component
+public class CardPopManagerImpl implements CardPopManager {
+
+    @Resource
+    private CardPopMapper cardPopMapper;
+
+    @Override
+    public int batchInsert(List<CardPopPO> list) {
+        if (list == null || list.isEmpty()) {
+            return 0;
+        }
+        return cardPopMapper.batchInsert(list);
+    }
+
+    @Override
+    public int deleteByBatchNo(String batchNo) {
+        if (batchNo == null || batchNo.trim().isEmpty()) {
+            return 0;
+        }
+        return cardPopMapper.deleteByBatchNo(batchNo);
+    }
+
+    @Override
+    public List<CardPopPO> selectByCardId(String cardId, String batchNo) {
+        // 卡片ID 或批次为空都无意义,直接返回空集
+        if (cardId == null || batchNo == null) {
+            return Collections.emptyList();
+        }
+        List<CardPopPO> list = cardPopMapper.selectByCardId(cardId, batchNo);
+        return list == null ? Collections.emptyList() : list;
+    }
+}

+ 44 - 0
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/impl/CardValueHistoryManagerImpl.java

@@ -0,0 +1,44 @@
+package com.mangoo.rating.recommend.manager.impl;
+
+import com.mangoo.rating.recommend.manager.CardValueHistoryManager;
+import com.mangoo.rating.recommend.mapper.CardValueHistoryMapper;
+import com.mangoo.rating.recommend.po.CardValueHistoryPO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 卡片价格历史 Manager 实现
+ *
+ * @author gengjintao
+ * @date 2026/06/25
+ */
+@Slf4j
+@Component
+public class CardValueHistoryManagerImpl implements CardValueHistoryManager {
+
+    @Resource
+    private CardValueHistoryMapper cardValueHistoryMapper;
+
+    @Override
+    public int batchUpsert(List<CardValueHistoryPO> list) {
+        if (list == null || list.isEmpty()) {
+            return 0;
+        }
+        return cardValueHistoryMapper.batchUpsert(list);
+    }
+
+    @Override
+    public List<CardValueHistoryPO> selectTrend(String cardId, LocalDate startDate) {
+        // cardId 为空无意义,直接返回空集;startDate 允许为空(查全部)
+        if (cardId == null || cardId.trim().isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<CardValueHistoryPO> list = cardValueHistoryMapper.selectTrend(cardId, startDate);
+        return list == null ? Collections.emptyList() : list;
+    }
+}

+ 34 - 12
mango-manager/src/main/java/com/mangoo/rating/recommend/manager/impl/RatingRecommendRuleManagerImpl.java

@@ -22,30 +22,52 @@ public class RatingRecommendRuleManagerImpl implements RatingRecommendRuleManage
     private RatingRecommendRuleMapper ratingRecommendRuleMapper;
 
     @Override
-    public RatingRecommendRulePO selectByExact(String player, String year, String series, String cardSet) {
-        // L1 参与字段全部不为空才查询(避免无意义 SQL)
-        if (isBlank(player) || isBlank(year) || isBlank(series) || isBlank(cardSet)) {
+    public RatingRecommendRulePO selectByExact(String player, String year, String series, String cardSet, String batchNo) {
+        // L1 参与字段全部不为空才查询(避免无意义 SQL);batchNo 为空直接返回 null(无生效批次不查)
+        if (isBlank(player) || isBlank(year) || isBlank(series) || isBlank(cardSet) || isBlank(batchNo)) {
             return null;
         }
-        return ratingRecommendRuleMapper.selectByExact(player, year, series, cardSet);
+        return ratingRecommendRuleMapper.selectByExact(player, year, series, cardSet, batchNo);
     }
 
     @Override
-    public RatingRecommendRulePO selectBySeriesSetYear(String series, String cardSet, String year) {
-        // L2 三个参与字段不能为空
-        if (isBlank(series) || isBlank(cardSet) || isBlank(year)) {
+    public RatingRecommendRulePO selectBySeriesSetYear(String series, String cardSet, String year, String batchNo) {
+        // L2 三个参与字段不能为空;batchNo 为空直接返回 null
+        if (isBlank(series) || isBlank(cardSet) || isBlank(year) || isBlank(batchNo)) {
             return null;
         }
-        return ratingRecommendRuleMapper.selectBySeriesSetYear(series, cardSet, year);
+        return ratingRecommendRuleMapper.selectBySeriesSetYear(series, cardSet, year, batchNo);
     }
 
     @Override
-    public RatingRecommendRulePO selectBySeriesSet(String series, String cardSet) {
-        // L3 两个参与字段不能为空
-        if (isBlank(series) || isBlank(cardSet)) {
+    public RatingRecommendRulePO selectBySeriesSet(String series, String cardSet, String batchNo) {
+        // L3 两个参与字段不能为空;batchNo 为空直接返回 null
+        if (isBlank(series) || isBlank(cardSet) || isBlank(batchNo)) {
             return null;
         }
-        return ratingRecommendRuleMapper.selectBySeriesSet(series, cardSet);
+        return ratingRecommendRuleMapper.selectBySeriesSet(series, cardSet, batchNo);
+    }
+
+    @Override
+    public int batchInsert(java.util.List<RatingRecommendRulePO> list) {
+        if (list == null || list.isEmpty()) {
+            return 0;
+        }
+        return ratingRecommendRuleMapper.batchInsert(list);
+    }
+
+    @Override
+    public int deleteByBatchNo(String batchNo) {
+        if (batchNo == null || batchNo.trim().isEmpty()) {
+            return 0;
+        }
+        return ratingRecommendRuleMapper.deleteByBatchNo(batchNo);
+    }
+
+    @Override
+    public java.util.List<String> selectDistinctBatchNos() {
+        java.util.List<String> list = ratingRecommendRuleMapper.selectDistinctBatchNos();
+        return list == null ? java.util.Collections.emptyList() : list;
     }
 
     /**