|
|
@@ -60,11 +60,12 @@ public class ProductRecommendationService {
|
|
|
List<Product> candidates = new ArrayList<>();
|
|
|
|
|
|
// 从 mapping 表获取关联商品
|
|
|
- List<ProductDimensionMapping> mappings = dimensionMappingMapper.selectList(
|
|
|
- new LambdaQueryWrapper<ProductDimensionMapping>()
|
|
|
- .eq(ProductDimensionMapping::getDimensionCode, dimensionCode)
|
|
|
- .eq(ProductDimensionMapping::getEnabled, 1)
|
|
|
- );
|
|
|
+ LambdaQueryWrapper<ProductDimensionMapping> mappingQw = new LambdaQueryWrapper<ProductDimensionMapping>()
|
|
|
+ .eq(ProductDimensionMapping::getEnabled, 1);
|
|
|
+ if (dimensionCode != null && !dimensionCode.isEmpty()) {
|
|
|
+ mappingQw.eq(ProductDimensionMapping::getDimensionCode, dimensionCode);
|
|
|
+ }
|
|
|
+ List<ProductDimensionMapping> mappings = dimensionMappingMapper.selectList(mappingQw);
|
|
|
|
|
|
if (mappings != null && !mappings.isEmpty()) {
|
|
|
List<Long> mappedProductIds = mappings.stream()
|
|
|
@@ -106,14 +107,17 @@ public class ProductRecommendationService {
|
|
|
|
|
|
// fallback: 从 Product.domain 匹配
|
|
|
if (candidates.isEmpty()) {
|
|
|
- List<Product> domainMatched = productMapper.selectList(
|
|
|
- new LambdaQueryWrapper<Product>()
|
|
|
- .eq(Product::getDomain, dimensionCode)
|
|
|
- .eq(Product::getStatus, "上架")
|
|
|
- .gt(Product::getStock, 0)
|
|
|
- .notIn(!purchasedIds.isEmpty(), Product::getId, purchasedIds)
|
|
|
- .orderByAsc(Product::getSortOrder)
|
|
|
- );
|
|
|
+ LambdaQueryWrapper<Product> domainQw = new LambdaQueryWrapper<Product>()
|
|
|
+ .eq(Product::getStatus, "上架")
|
|
|
+ .gt(Product::getStock, 0)
|
|
|
+ .orderByAsc(Product::getSortOrder);
|
|
|
+ if (dimensionCode != null && !dimensionCode.isEmpty()) {
|
|
|
+ domainQw.eq(Product::getDomain, dimensionCode);
|
|
|
+ }
|
|
|
+ if (!purchasedIds.isEmpty()) {
|
|
|
+ domainQw.notIn(Product::getId, purchasedIds);
|
|
|
+ }
|
|
|
+ List<Product> domainMatched = productMapper.selectList(domainQw);
|
|
|
candidates.addAll(domainMatched);
|
|
|
}
|
|
|
|
|
|
@@ -256,6 +260,9 @@ public class ProductRecommendationService {
|
|
|
* 对低得分维度加权 boost
|
|
|
*/
|
|
|
private double applyDimensionBoost(int baseScore, String dimensionCode, Map<String, Integer> memberScores) {
|
|
|
+ if (dimensionCode == null || dimensionCode.isEmpty()) {
|
|
|
+ return baseScore;
|
|
|
+ }
|
|
|
Integer score = memberScores.get(dimensionCode);
|
|
|
if (score == null || score >= 70) {
|
|
|
return baseScore;
|
|
|
@@ -271,6 +278,14 @@ public class ProductRecommendationService {
|
|
|
*/
|
|
|
private double calculateMatchScore(Product product, String dimensionCode, Map<String, Integer> memberScores) {
|
|
|
int base = 70;
|
|
|
+ if (dimensionCode == null || dimensionCode.isEmpty()) {
|
|
|
+ Integer minScore = memberScores.values().stream().min(Integer::compareTo).orElse(null);
|
|
|
+ if (minScore != null) {
|
|
|
+ if (minScore < 50) base = 90;
|
|
|
+ else if (minScore < 70) base = 80;
|
|
|
+ }
|
|
|
+ return base;
|
|
|
+ }
|
|
|
Integer myScore = memberScores.get(dimensionCode);
|
|
|
if (myScore != null) {
|
|
|
if (myScore < 50) base = 90;
|
|
|
@@ -284,6 +299,9 @@ public class ProductRecommendationService {
|
|
|
* 构建推荐理由
|
|
|
*/
|
|
|
private String buildRecommendationReason(Product product, String dimensionCode, Map<String, Integer> memberScores) {
|
|
|
+ if (dimensionCode == null || dimensionCode.isEmpty()) {
|
|
|
+ return "为您推荐的好物";
|
|
|
+ }
|
|
|
Integer score = memberScores.get(dimensionCode);
|
|
|
if (score == null) {
|
|
|
return "根据您的维度匹配为您推荐";
|