Преглед на файлове

fix(recommend): 维度商品推荐修复订单状态匹配与实物库存口径

已支付状态改用paid等真实枚举;库存仅physical商品要求>0(与下单校验对齐),虚拟商品不再被误杀

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Sisyphus преди 4 дни
родител
ревизия
e0904c5358
променени са 1 файла, в които са добавени 14 реда и са изтрити 6 реда
  1. 14 6
      cfc-backend/src/main/java/com/etotem/cfc/service/ProductRecommendationService.java

+ 14 - 6
cfc-backend/src/main/java/com/etotem/cfc/service/ProductRecommendationService.java

@@ -89,7 +89,7 @@ public class ProductRecommendationService {
                         new LambdaQueryWrapper<Product>()
                         .in(Product::getId, mappedProductIds)
                                 .eq(Product::getStatus, "on_shelf")
-                                .gt(Product::getStock, 0)
+                                .and(w -> w.ne(Product::getProductType, "physical").or().isNull(Product::getStock).or().gt(Product::getStock, 0))
                                 .orderByAsc(Product::getSortOrder)
                 );
 
@@ -139,7 +139,7 @@ public class ProductRecommendationService {
         if (candidates.isEmpty()) {
             LambdaQueryWrapper<Product> domainQw = new LambdaQueryWrapper<Product>()
                     .eq(Product::getStatus, "on_shelf")
-                    .gt(Product::getStock, 0)
+                    .and(w -> w.ne(Product::getProductType, "physical").or().isNull(Product::getStock).or().gt(Product::getStock, 0))
                     .orderByAsc(Product::getSortOrder);
             if (dimensionCode != null && !dimensionCode.isEmpty()) {
                 domainQw.eq(Product::getDomain, dimensionCode);
@@ -261,7 +261,7 @@ public class ProductRecommendationService {
             if (excludeProductIds != null && excludeProductIds.contains(assoc.getTargetProductId())) continue;
 
             Product product = productMapper.selectById(assoc.getTargetProductId());
-            if (product == null || !"on_shelf".equals(product.getStatus()) || product.getStock() <= 0) continue;
+            if (product == null || !"on_shelf".equals(product.getStatus()) || !hasSellableStock(product)) continue;
 
             Map<String, Object> item = new LinkedHashMap<>();
             item.put("id", product.getId());
@@ -327,7 +327,7 @@ public class ProductRecommendationService {
             if (excludeProductIds != null && excludeProductIds.contains(targetId)) continue;
 
             Product product = productMapper.selectById(targetId);
-            if (product == null || !"on_shelf".equals(product.getStatus()) || product.getStock() <= 0) continue;
+            if (product == null || !"on_shelf".equals(product.getStatus()) || !hasSellableStock(product)) continue;
 
             Map<String, Object> item = new LinkedHashMap<>();
             item.put("id", product.getId());
@@ -377,7 +377,7 @@ public class ProductRecommendationService {
             if (excludeProductIds != null && excludeProductIds.contains(targetId)) continue;
 
             Product product = productMapper.selectById(targetId);
-            if (product == null || !"on_shelf".equals(product.getStatus()) || product.getStock() <= 0) continue;
+            if (product == null || !"on_shelf".equals(product.getStatus()) || !hasSellableStock(product)) continue;
 
             Map<String, Object> item = new LinkedHashMap<>();
             item.put("id", product.getId());
@@ -432,6 +432,14 @@ public class ProductRecommendationService {
 
     // ── 原有私有辅助方法(保持不变)──
 
+    // 仅实物商品要求库存>0(库存NULL视为可购),与 ProductOrderService 下单校验口径一致;虚拟商品不看库存
+    private boolean hasSellableStock(Product product) {
+        if (!"physical".equals(product.getProductType())) {
+            return true;
+        }
+        return product.getStock() == null || product.getStock() > 0;
+    }
+
     /**
      * 获取家庭成员在90天内购买过的商品ID
      */
@@ -446,7 +454,7 @@ public class ProductRecommendationService {
         List<ProductOrder> orders = orderMapper.selectList(
                 new LambdaQueryWrapper<ProductOrder>()
                         .eq(ProductOrder::getFamilyId, familyId)
-                        .eq(ProductOrder::getStatus, "已支付")
+                        .in(ProductOrder::getStatus, "paid", "pending_receipt", "shipped", "completed")
                         .gt(ProductOrder::getPaidAt, cutoff)
         );