搜索优化

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

View File

@ -316,7 +316,7 @@
<el-table <el-table
:data="filteredCompareTableData" :data="filteredCompareTableData"
border border
height="60vh" :height="isFullscreen ? '90vh' : '60vh'"
style="width: 100%; min-width: 600px" style="width: 100%; min-width: 600px"
> >
<el-table-column <el-table-column
@ -482,6 +482,7 @@ const activePossibleFieldIndex = ref(-1);
const allFields = ref([]); const allFields = ref([]);
const fieldValueMap = ref({}); const fieldValueMap = ref({});
const allValues = ref([]); const allValues = ref([]);
const fieldsFromApi = ref(false); //
const hintTimer = ref(null); const hintTimer = ref(null);
const pendingSearchTimer = ref(null); const pendingSearchTimer = ref(null);
const differenceTimer = ref(null); const differenceTimer = ref(null);
@ -1044,13 +1045,16 @@ const triggerConditionSuggestions = (conditionText) => {
valueFieldCounts[val.fieldKey].count += val.weight; valueFieldCounts[val.fieldKey].count += val.weight;
}); });
possibleFields.value = Object.values(valueFieldCounts) //
.filter( if (!fieldsFromApi.value) {
(item) => possibleFields.value = Object.values(valueFieldCounts)
item.count > 1 && item.field && !usedLabels.has(item.field.label) .filter(
) (item) =>
.sort((a, b) => b.count - a.count) item.count > 1 && item.field && !usedLabels.has(item.field.label)
.map((item) => item.field); )
.sort((a, b) => b.count - a.count)
.map((item) => item.field);
}
// //
let allSuggestions = [...fieldSuggestions, ...valueSuggestions]; let allSuggestions = [...fieldSuggestions, ...valueSuggestions];
@ -1155,14 +1159,16 @@ const updateSuggestionsFromValue = (value) => {
valueFieldCounts[val.fieldKey].count += val.weight; valueFieldCounts[val.fieldKey].count += val.weight;
}); });
// //
possibleFields.value = Object.values(valueFieldCounts) if (!fieldsFromApi.value) {
.filter( possibleFields.value = Object.values(valueFieldCounts)
(item) => .filter(
item.count > 1 && item.field && !usedLabels.has(item.field.label) (item) =>
) // 使 item.count > 1 && item.field && !usedLabels.has(item.field.label)
.sort((a, b) => b.count - a.count) // ) // 使
.map((item) => item.field); .sort((a, b) => b.count - a.count) //
.map((item) => item.field);
}
valueSuggestions = potentialValues; valueSuggestions = potentialValues;
} else { } else {
@ -1250,6 +1256,11 @@ const updateSuggestionsFromValue = (value) => {
// //
const handleInput = (value, options = {}) => { const handleInput = (value, options = {}) => {
const normalizedValue = value ?? ""; const normalizedValue = value ?? "";
//
if (!normalizedValue.trim()) {
fieldsFromApi.value = false;
possibleFields.value = [];
}
updateSuggestionsFromValue(normalizedValue); updateSuggestionsFromValue(normalizedValue);
if (!normalizedValue.trim()) { if (!normalizedValue.trim()) {
keyDiffFields.value = []; keyDiffFields.value = [];
@ -1316,8 +1327,127 @@ const fetchSearchHints = async (keyword) => {
: Array.isArray(res) : Array.isArray(res)
? 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); 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) { } catch (error) {
console.error("searchHint error:", error); console.error("searchHint error:", error);
} }
@ -1912,6 +2042,7 @@ const clearAll = () => {
showResults.value = false; showResults.value = false;
showSuggestions.value = false; showSuggestions.value = false;
possibleFields.value = []; possibleFields.value = [];
fieldsFromApi.value = false; //
selectedConditionIndex.value = -1; selectedConditionIndex.value = -1;
// //
keyDiffFields.value = []; keyDiffFields.value = [];