|
|
@@ -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)
|
|
|
);
|
|
|
|