fix: 优化鱼类智能查询

This commit is contained in:
tangwei 2026-04-29 11:52:20 +08:00
parent de0a291f70
commit 1239b58fee
4 changed files with 100 additions and 69 deletions

View File

@ -1,5 +1,6 @@
package com.yfd.platform.env.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -72,106 +73,136 @@ public class SdFishDictoryBServiceImpl extends ServiceImpl<SdFishDictoryBMapper,
return Collections.emptyList();
}
int resultLimit = (limit != null && limit > 0) ? limit : 10;
String searchName = name.trim();
LambdaQueryWrapper<SdFishDictoryB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFishDictoryB::getIsDeleted, 0);
List<SdFishDictoryB> allFish = list(wrapper);
SdFishDictoryB referenceFish = allFish.stream()
SdFishDictoryB exactMatch = allFish.stream()
.filter(f -> f.getName() != null && f.getName().equals(searchName))
.findFirst()
.orElse(null);
if (referenceFish == null) {
referenceFish = allFish.stream()
.filter(f -> f.getName() != null && f.getName().contains(searchName))
.findFirst()
.orElse(null);
}
if (referenceFish == null && allFish.stream().anyMatch(f ->
f.getName() != null && (f.getName().contains(searchName) || searchName.contains(f.getName())))) {
final String searchNameFinal = searchName;
referenceFish = allFish.stream()
.filter(f -> f.getName() != null &&
(f.getName().contains(searchNameFinal) || searchNameFinal.contains(f.getName())))
.findFirst()
.orElse(null);
}
if (referenceFish == null) {
return allFish.stream()
.filter(f -> f.getName() != null && f.getName().contains(searchName))
.limit(limit != null ? limit : 10)
.collect(Collectors.toList());
}
final SdFishDictoryB finalRefFish = referenceFish;
if (exactMatch != null) {
Map<SdFishDictoryB, Integer> similarityMap = new HashMap<>();
for (SdFishDictoryB fish : allFish) {
if (fish.getId().equals(finalRefFish.getId())) {
if (fish.getId().equals(exactMatch.getId())) {
continue;
}
int score = calculateSimilarity(finalRefFish, fish);
int score = calculateSimilarity(exactMatch, fish);
if (score > 0) {
similarityMap.put(fish, score);
}
}
return similarityMap.entrySet().stream()
List<SdFishDictoryB> result = similarityMap.entrySet().stream()
.sorted(Map.Entry.<SdFishDictoryB, Integer>comparingByValue().reversed())
.limit(limit != null ? limit : 10)
.limit(resultLimit)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
result.add(0, exactMatch);
return result;
}
List<SdFishDictoryB> containsMatches = allFish.stream()
.filter(f -> f.getName() != null && f.getName().contains(searchName))
.collect(Collectors.toList());
if (!containsMatches.isEmpty()) {
List<SdFishDictoryB> result = containsMatches.stream()
.sorted((f1, f2) -> {
int len1 = f1.getName().length();
int len2 = f2.getName().length();
if (len1 != len2) {
return Integer.compare(len1, len2);
}
return f1.getName().compareTo(f2.getName());
})
.limit(resultLimit)
.collect(Collectors.toList());
return result;
}
SdFishDictoryB partialMatch = allFish.stream()
.filter(f -> f.getName() != null && (searchName.contains(f.getName()) || f.getName().contains(searchName)))
.findFirst()
.orElse(null);
if (partialMatch != null) {
Map<SdFishDictoryB, Integer> similarityMap = new HashMap<>();
for (SdFishDictoryB fish : allFish) {
if (fish.getId().equals(partialMatch.getId())) {
continue;
}
int score = calculateSimilarity(partialMatch, fish);
if (score > 0) {
similarityMap.put(fish, score);
}
}
List<SdFishDictoryB> result = similarityMap.entrySet().stream()
.sorted(Map.Entry.<SdFishDictoryB, Integer>comparingByValue().reversed())
.limit(resultLimit)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
result.add(0, partialMatch);
return result;
}
return Collections.emptyList();
}
private int calculateSimilarity(SdFishDictoryB ref, SdFishDictoryB target) {
int score = 0;
if (ref.getOrders() != null && ref.getOrders().equals(target.getOrders())) {
score += 3;
if (ref.getGenus() != null && ref.getGenus().equals(target.getGenus()) && !ref.getGenus().isEmpty()) {
score += 25;
}
if (ref.getFamily() != null && ref.getFamily().equals(target.getFamily())) {
score += 5;
if (ref.getSpecies() != null && ref.getSpecies().equals(target.getSpecies()) && !ref.getSpecies().isEmpty()) {
score += 20;
}
if (ref.getGenus() != null && ref.getGenus().equals(target.getGenus())) {
score += 8;
if (ref.getFamily() != null && ref.getFamily().equals(target.getFamily()) && !ref.getFamily().isEmpty()) {
score += 15;
}
if (ref.getSpecies() != null && ref.getSpecies().equals(target.getSpecies())) {
if (ref.getOrders() != null && ref.getOrders().equals(target.getOrders()) && !ref.getOrders().isEmpty()) {
score += 10;
}
if (ref.getType() != null && ref.getType().equals(target.getType())) {
score += 2;
if (ref.getType() != null && ref.getType().equals(target.getType()) && !ObjectUtil.isEmpty(ref.getType()) ) {
score += 5;
}
if (ref.getHabitat() != null && ref.getHabitat().equals(target.getHabitat())) {
if (ref.getHabitat() != null && ref.getHabitat().equals(target.getHabitat()) && !ObjectUtil.isEmpty(ref.getHabitat())) {
score += 5;
}
if (ref.getHabitMigrat() != null && ref.getHabitMigrat().equals(target.getHabitMigrat()) && !ref.getHabitMigrat().isEmpty()) {
score += 5;
}
if (ref.getFeedingHabit() != null && ref.getFeedingHabit().equals(target.getFeedingHabit()) && !ref.getFeedingHabit().isEmpty()) {
score += 3;
}
if (ref.getRare() != null && ref.getRare().equals(target.getRare())) {
score += 2;
}
if (ref.getPtype() != null && ref.getPtype().equals(target.getPtype())) {
score += 2;
}
if (ref.getResourceType() != null && ref.getResourceType().equals(target.getResourceType())) {
score += 2;
}
if (ref.getHabitMigrat() != null && ref.getHabitMigrat().equals(target.getHabitMigrat())) {
if (ref.getSpawnCharact() != null && ref.getSpawnCharact().equals(target.getSpawnCharact()) && !ref.getSpawnCharact().isEmpty()) {
score += 3;
}
if (ref.getFeedingHabit() != null && ref.getFeedingHabit().equals(target.getFeedingHabit())) {
if (ref.getPtype() != null && ref.getPtype().equals(target.getPtype()) && !ObjectUtil.isEmpty(ref.getPtype())) {
score += 2;
}
if (ref.getSpawnCharact() != null && ref.getSpawnCharact().equals(target.getSpawnCharact())) {
if (ref.getResourceType() != null && ref.getResourceType().equals(target.getResourceType()) && !ObjectUtil.isEmpty(ref.getResourceType())) {
score += 2;
}
if (ref.getRare() != null && ref.getRare().equals(target.getRare()) && !ObjectUtil.isEmpty(ref.getRare())) {
score += 2;
}

View File

@ -10,12 +10,12 @@ spring:
druid:
master:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
slave:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"

View File

@ -10,12 +10,12 @@ spring:
druid:
master:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
slave:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}"
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"

View File

@ -1,6 +1,6 @@
spring:
profiles:
active: devtw
active: prod
jasypt:
encryptor: