搜索优化

This commit is contained in:
JenniferW 2025-12-16 14:52:06 +08:00
parent 5da552d803
commit e990847c45
2 changed files with 151 additions and 20 deletions

View File

@ -1,11 +1,11 @@
import request from '@/utils/request'
// 智能搜索接口 - 根据输入内容获取对应的key和value
export function searchHint(query) {
export function searchHint(data) {
return request({
url: '/products/search/smart',
method: 'get',
params: query
method: 'post',
data: data
})
}

View File

@ -316,7 +316,7 @@
<el-table
:data="filteredCompareTableData"
border
height="60vh"
:height="isFullscreen ? '90vh' : '60vh'"
style="width: 100%; min-width: 600px"
>
<el-table-column
@ -482,6 +482,7 @@ const activePossibleFieldIndex = ref(-1);
const allFields = ref([]);
const fieldValueMap = ref({});
const allValues = ref([]);
const fieldsFromApi = ref(false); //
const hintTimer = ref(null);
const pendingSearchTimer = ref(null);
const differenceTimer = ref(null);
@ -1044,13 +1045,16 @@ const triggerConditionSuggestions = (conditionText) => {
valueFieldCounts[val.fieldKey].count += val.weight;
});
possibleFields.value = Object.values(valueFieldCounts)
.filter(
(item) =>
item.count > 1 && item.field && !usedLabels.has(item.field.label)
)
.sort((a, b) => b.count - a.count)
.map((item) => item.field);
//
if (!fieldsFromApi.value) {
possibleFields.value = Object.values(valueFieldCounts)
.filter(
(item) =>
item.count > 1 && item.field && !usedLabels.has(item.field.label)
)
.sort((a, b) => b.count - a.count)
.map((item) => item.field);
}
//
let allSuggestions = [...fieldSuggestions, ...valueSuggestions];
@ -1155,14 +1159,16 @@ const updateSuggestionsFromValue = (value) => {
valueFieldCounts[val.fieldKey].count += val.weight;
});
//
possibleFields.value = Object.values(valueFieldCounts)
.filter(
(item) =>
item.count > 1 && item.field && !usedLabels.has(item.field.label)
) // 使
.sort((a, b) => b.count - a.count) //
.map((item) => item.field);
//
if (!fieldsFromApi.value) {
possibleFields.value = Object.values(valueFieldCounts)
.filter(
(item) =>
item.count > 1 && item.field && !usedLabels.has(item.field.label)
) // 使
.sort((a, b) => b.count - a.count) //
.map((item) => item.field);
}
valueSuggestions = potentialValues;
} else {
@ -1250,6 +1256,11 @@ const updateSuggestionsFromValue = (value) => {
//
const handleInput = (value, options = {}) => {
const normalizedValue = value ?? "";
//
if (!normalizedValue.trim()) {
fieldsFromApi.value = false;
possibleFields.value = [];
}
updateSuggestionsFromValue(normalizedValue);
if (!normalizedValue.trim()) {
keyDiffFields.value = [];
@ -1316,8 +1327,127 @@ const fetchSearchHints = async (keyword) => {
: Array.isArray(res)
? res
: [];
//
if (!hintList.length) {
if (!allFields.value.length) {
suggestions.value = [];
possibleFields.value = [];
allFields.value = [];
allValues.value = [];
fieldValueMap.value = {};
fieldsFromApi.value = false;
showSuggestions.value = false;
return;
}
//
updateSuggestionsFromValue(currentInput.value);
showSuggestions.value = suggestions.value.length > 0;
return;
}
//
mergeFieldMetadata(hintList);
updateSuggestionsFromValue(currentInput.value);
// ""
//
const parts = currentInput.value.split(/[;]/);
const currentPart = parts[parts.length - 1]?.trim() || "";
const cursorIndex = findCursorConditionIndex();
const isEditingExistingField =
cursorIndex >= 0 && cursorIndex < parts.length - 1;
if (
!isEditingExistingField &&
!currentPart.includes(":") &&
hintList.length > 0
) {
// fieldName
const fieldsFromHint = hintList
.filter((item) => item.fieldName && item.fieldKey)
.map((item) => ({
key: item.fieldKey,
label: item.fieldName,
}));
// 使
const usedLabels = getUsedFieldLabels(cursorIndex);
const uniqueFields = fieldsFromHint.filter(
(field) => !usedLabels.has(field.label)
);
//
if (currentPart) {
const valueQuery = currentPart.includes(":")
? currentPart.split(":").slice(1).join(":").trim()
: currentPart;
const valueQueryLower = valueQuery.toLowerCase();
const matchingFields = uniqueFields.filter((field) => {
const fieldItem = hintList.find(
(item) => item.fieldKey === field.key
);
if (!fieldItem || !Array.isArray(fieldItem.fieldValues)) return false;
return fieldItem.fieldValues.some((value) =>
String(value).toLowerCase().includes(valueQueryLower)
);
});
//
possibleFields.value =
matchingFields.length > 0 ? matchingFields : uniqueFields;
} else {
possibleFields.value = uniqueFields;
}
//
fieldsFromApi.value = true;
} else {
possibleFields.value = [];
fieldsFromApi.value = false;
}
// fieldValues
const valueQuery = currentPart.includes(":")
? currentPart.split(":").slice(1).join(":").trim()
: currentPart;
const valueQueryLower = (valueQuery || "").toLowerCase();
const apiValueSuggestions = [];
hintList.forEach((item) => {
if (!Array.isArray(item.fieldValues)) return;
const fieldKey = item.fieldKey || item.key || "";
const fieldLabel = item.fieldName || item.label || item.fieldLabel || "";
item.fieldValues.forEach((val) => {
const strVal =
val === null || val === undefined ? "" : String(val).trim();
if (!strVal) return;
if (
valueQueryLower &&
!strVal.toLowerCase().includes(valueQueryLower)
) {
return;
}
apiValueSuggestions.push({
type: "value",
label: strVal,
value: strVal,
fieldKey,
fieldLabel,
weight: 5, //
});
});
});
//
const seen = new Set();
const uniqueSuggestions = [];
apiValueSuggestions.forEach((s) => {
const key = s.label; //
if (seen.has(key)) return;
seen.add(key);
uniqueSuggestions.push(s);
});
suggestions.value = uniqueSuggestions;
showSuggestions.value = uniqueSuggestions.length > 0;
} catch (error) {
console.error("searchHint error:", error);
}
@ -1912,6 +2042,7 @@ const clearAll = () => {
showResults.value = false;
showSuggestions.value = false;
possibleFields.value = [];
fieldsFromApi.value = false; //
selectedConditionIndex.value = -1;
//
keyDiffFields.value = [];