查询条件优化
This commit is contained in:
parent
777d2bf8b3
commit
5da552d803
|
|
@ -982,10 +982,101 @@ const triggerConditionSuggestions = (conditionText) => {
|
||||||
|
|
||||||
suggestions.value = fieldValues.slice(0, 8);
|
suggestions.value = fieldValues.slice(0, 8);
|
||||||
possibleFields.value = []; // 已有字段时不显示可能的字段
|
possibleFields.value = []; // 已有字段时不显示可能的字段
|
||||||
|
} else {
|
||||||
|
// 字段无效,显示所有值
|
||||||
|
const allValueSuggestions = allValues.value
|
||||||
|
.filter((item) =>
|
||||||
|
String(item.value).toLowerCase().includes(conditionText.toLowerCase())
|
||||||
|
)
|
||||||
|
.map((item) => ({
|
||||||
|
type: "value",
|
||||||
|
label: item.value,
|
||||||
|
value: item.value,
|
||||||
|
fieldKey: item.fieldKey,
|
||||||
|
fieldLabel: item.fieldLabel,
|
||||||
|
weight: item.weight,
|
||||||
|
}));
|
||||||
|
suggestions.value = allValueSuggestions.slice(0, 8);
|
||||||
|
possibleFields.value = [];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 只有值,没有字段,使用原有逻辑
|
// 只有值,没有字段,直接查找匹配的建议(避免递归调用)
|
||||||
handleInput(currentInput.value, { skipDifference: true });
|
const cursorIndex = findCursorConditionIndex();
|
||||||
|
const usedLabels = getUsedFieldLabels(cursorIndex);
|
||||||
|
|
||||||
|
// 查找匹配的字段和值
|
||||||
|
const fieldSuggestions = allFields.value
|
||||||
|
.filter(
|
||||||
|
(field) =>
|
||||||
|
!usedLabels.has(field.label) &&
|
||||||
|
field.label.toLowerCase().includes(conditionText.toLowerCase())
|
||||||
|
)
|
||||||
|
.map((field) => ({
|
||||||
|
type: "field",
|
||||||
|
label: field.label,
|
||||||
|
value: field.key,
|
||||||
|
weight: 3,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const valueSuggestions = allValues.value
|
||||||
|
.filter((item) =>
|
||||||
|
String(item.value).toLowerCase().includes(conditionText.toLowerCase())
|
||||||
|
)
|
||||||
|
.map((item) => ({
|
||||||
|
type: "value",
|
||||||
|
label: item.value,
|
||||||
|
value: item.value,
|
||||||
|
fieldKey: item.fieldKey,
|
||||||
|
fieldLabel: item.fieldLabel,
|
||||||
|
weight: item.weight,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 检查是否有值强烈匹配某个字段
|
||||||
|
const valueFieldCounts = {};
|
||||||
|
valueSuggestions.forEach((val) => {
|
||||||
|
if (!valueFieldCounts[val.fieldKey]) {
|
||||||
|
valueFieldCounts[val.fieldKey] = {
|
||||||
|
count: 0,
|
||||||
|
label: val.fieldLabel,
|
||||||
|
field: allFields.value.find((f) => f.key === val.fieldKey),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 合并建议并按相关性排序
|
||||||
|
let allSuggestions = [...fieldSuggestions, ...valueSuggestions];
|
||||||
|
allSuggestions.sort((a, b) => {
|
||||||
|
if (b.weight !== a.weight) {
|
||||||
|
return b.weight - a.weight;
|
||||||
|
}
|
||||||
|
const aMatch = a.label.toLowerCase().indexOf(conditionText.toLowerCase());
|
||||||
|
const bMatch = b.label.toLowerCase().indexOf(conditionText.toLowerCase());
|
||||||
|
if (aMatch !== bMatch) {
|
||||||
|
return aMatch - bMatch;
|
||||||
|
}
|
||||||
|
return a.label.length - b.label.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 去重并限制数量
|
||||||
|
const uniqueSuggestions = [];
|
||||||
|
const seenLabels = new Set();
|
||||||
|
allSuggestions.forEach((suggestion) => {
|
||||||
|
if (!seenLabels.has(suggestion.label)) {
|
||||||
|
seenLabels.add(suggestion.label);
|
||||||
|
uniqueSuggestions.push(suggestion);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestions.value = uniqueSuggestions.slice(0, 8);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1182,8 +1273,45 @@ const handleInput = (value, options = {}) => {
|
||||||
const fetchSearchHints = async (keyword) => {
|
const fetchSearchHints = async (keyword) => {
|
||||||
if (!keyword) return;
|
if (!keyword) return;
|
||||||
try {
|
try {
|
||||||
const res = await searchHint({ keyword });
|
// 先解析当前输入的条件
|
||||||
const hintList = Array.isArray(res?.data)
|
const conditions = parseConditions(currentInput.value);
|
||||||
|
|
||||||
|
// 构建 fieldConditions
|
||||||
|
const fieldConditions = conditions
|
||||||
|
.filter((condition) => condition.value)
|
||||||
|
.map((condition) => {
|
||||||
|
// 如果明确选择了字段(有 field 且 valid),使用 fieldName 和 fieldValue
|
||||||
|
if (condition.field && condition.valid) {
|
||||||
|
return {
|
||||||
|
fieldName: condition.field, // 使用 fieldKey
|
||||||
|
fieldValue: condition.value, // 对应的 value
|
||||||
|
keyword: "",
|
||||||
|
queryType: "FUZZY",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不确定输入的值是 label 还是 value,全部放 keyword
|
||||||
|
return {
|
||||||
|
fieldName: "",
|
||||||
|
fieldValue: "",
|
||||||
|
keyword: condition.value,
|
||||||
|
queryType: "FUZZY",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
fieldConditions,
|
||||||
|
inputWord: currentInput.value.trim(),
|
||||||
|
page: 0,
|
||||||
|
size: pageSize.value,
|
||||||
|
};
|
||||||
|
const res = await searchHint(payload);
|
||||||
|
const pageData = res?.data ?? res ?? {};
|
||||||
|
const hintList = Array.isArray(pageData?.content)
|
||||||
|
? pageData.content
|
||||||
|
: Array.isArray(pageData)
|
||||||
|
? pageData
|
||||||
|
: Array.isArray(res?.data)
|
||||||
? res.data
|
? res.data
|
||||||
: Array.isArray(res)
|
: Array.isArray(res)
|
||||||
? res
|
? res
|
||||||
|
|
@ -1351,7 +1479,8 @@ const selectSuggestion = (item) => {
|
||||||
currentInput.value = parts.join(";").replace(/;;+/g, ";").trim();
|
currentInput.value = parts.join(";").replace(/;;+/g, ";").trim();
|
||||||
|
|
||||||
// 检查是否添加了分号(选择值建议时会自动添加分号)
|
// 检查是否添加了分号(选择值建议时会自动添加分号)
|
||||||
const hasAddedSemicolon = item.type === "value" && parts[targetIndex].trim().endsWith(";");
|
const hasAddedSemicolon =
|
||||||
|
item.type === "value" && parts[targetIndex].trim().endsWith(";");
|
||||||
|
|
||||||
// 保持建议框显示,允许继续编辑
|
// 保持建议框显示,允许继续编辑
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -1541,6 +1670,31 @@ const buildFieldConditionsPayload = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 为 searchHint 构建 fieldConditions
|
||||||
|
const buildFieldConditionsForHint = () => {
|
||||||
|
return parsedConditions.value
|
||||||
|
.filter((condition) => condition.value)
|
||||||
|
.map((condition) => {
|
||||||
|
// 如果明确选择了字段(有 field 且 valid),使用 fieldName 和 fieldValue
|
||||||
|
if (condition.field && condition.valid) {
|
||||||
|
return {
|
||||||
|
fieldName: condition.field, // 使用 fieldKey
|
||||||
|
fieldValue: condition.value, // 对应的 value
|
||||||
|
keyword: "",
|
||||||
|
queryType: "FUZZY",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不确定输入的值是 label 还是 value,全部放 keyword
|
||||||
|
return {
|
||||||
|
fieldName: "",
|
||||||
|
fieldValue: "",
|
||||||
|
keyword: condition.value,
|
||||||
|
queryType: "FUZZY",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const executeSearch = async ({ page = currentPage.value } = {}) => {
|
const executeSearch = async ({ page = currentPage.value } = {}) => {
|
||||||
if (pendingSearchTimer.value) {
|
if (pendingSearchTimer.value) {
|
||||||
clearTimeout(pendingSearchTimer.value);
|
clearTimeout(pendingSearchTimer.value);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue