From a6c0293205a87e92e62659467ccfe12744aaaf40 Mon Sep 17 00:00:00 2001 From: JenniferW <1627055433@qq.com> Date: Mon, 22 Dec 2025 11:06:14 +0800 Subject: [PATCH] =?UTF-8?q?tag=E5=90=8C=E6=AD=A5=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/order/intention/search.vue | 168 ++++++++++++++++----------- 1 file changed, 103 insertions(+), 65 deletions(-) diff --git a/src/views/order/intention/search.vue b/src/views/order/intention/search.vue index f955632..e012893 100644 --- a/src/views/order/intention/search.vue +++ b/src/views/order/intention/search.vue @@ -1323,13 +1323,19 @@ const handleInput = (value, options = {}) => { // 如果该条件的内容发生了变化,将其移到最后一个位置,并清除原位置 if (lastPart !== currentPart) { // 获取被编辑的条件 - const editedPart = currentPart; + const editedPart = currentPart.trim(); + + // 保存原条件的索引,用于清理精准查询条件 + const oldConditionIndex = cursorIndex; // 移除原位置的条件,并将编辑后的条件添加到最后一个位置 const newParts = currentParts.filter( (_, index) => index !== cursorIndex ); - newParts.push(editedPart); + // 如果编辑后的条件不为空,才添加到末尾 + if (editedPart) { + newParts.push(editedPart); + } const newValue = newParts.join(";"); // 标记条件刚刚被移动,避免使用本地缓存 @@ -1341,9 +1347,51 @@ const handleInput = (value, options = {}) => { // 更新输入框的值(使用 skipReorder 避免无限循环) currentInput.value = newValue; - // 重新解析条件,不使用缓存 + // 重新解析条件,确保使用最新的条件顺序 parsedConditions.value = parseConditions(newValue); - syncPreciseConditionsIndex(); + + // 清理精准查询条件:如果原条件有精准查询标记,需要移除或更新 + if (preciseConditions.value.length > 0) { + // 找到引用原索引的精准查询条件 + const preciseIndex = preciseConditions.value.findIndex( + (cond) => cond.originalIndex === oldConditionIndex + ); + if (preciseIndex !== -1) { + // 如果编辑后的条件不为空,尝试更新精准查询条件的索引 + if (editedPart) { + // 重新解析编辑后的条件,看是否能匹配到精准查询条件 + const editedCondition = parseConditions(editedPart)[0]; + if (editedCondition) { + // 查找新条件在新列表中的索引 + const newIndex = parsedConditions.value.findIndex( + (c) => + c.field === editedCondition.field && + c.value === editedCondition.value && + c.fieldLabel === editedCondition.fieldLabel + ); + if (newIndex !== -1) { + // 更新精准查询条件的索引 + preciseConditions.value[preciseIndex] = { + ...preciseConditions.value[preciseIndex], + ...editedCondition, + originalIndex: newIndex, + }; + } else { + // 如果找不到匹配的条件,移除精准查询条件 + preciseConditions.value.splice(preciseIndex, 1); + } + } else { + // 如果解析失败,移除精准查询条件 + preciseConditions.value.splice(preciseIndex, 1); + } + } else { + // 如果编辑后的条件为空,移除精准查询条件 + preciseConditions.value.splice(preciseIndex, 1); + } + } + // 同步其他精准查询条件的索引 + syncPreciseConditionsIndex(); + } // 清空建议,不从本地缓存获取 suggestions.value = []; @@ -1366,6 +1414,11 @@ const handleInput = (value, options = {}) => { }, 100); }); + // 触发实时搜索,使用最新的条件顺序 + if (newValue.trim()) { + triggerRealTimeSearch(); + } + // 触发搜索提示(只针对最后一个条件) const finalPart = editedPart; if (finalPart && !options.skipFetch) { @@ -1398,6 +1451,27 @@ const handleInput = (value, options = {}) => { return; } + // 同步更新 parsedConditions,确保 tag 显示与输入框内容一致 + const newConditions = parseConditions(normalizedValue); + parsedConditions.value = newConditions; + + // 清理不再存在的精准查询条件 + if (preciseConditions.value.length > 0) { + preciseConditions.value = preciseConditions.value.filter((preciseCond) => { + // 检查精准查询条件是否在新的条件列表中存在 + const exists = newConditions.some( + (cond) => + cond.field === preciseCond.field && + cond.value === preciseCond.value && + cond.fieldLabel === preciseCond.fieldLabel + ); + return exists; + }); + } + + // 同步精准查询条件的索引 + syncPreciseConditionsIndex(); + updateSuggestionsFromValue(normalizedValue); if (options.skipFetch) { return; @@ -1413,26 +1487,11 @@ const handleInput = (value, options = {}) => { const fetchSearchHints = async (keyword) => { if (!keyword) return; try { - // 先解析当前输入的条件 + // 始终基于最新的 currentInput.value 解析条件,确保使用最新的条件顺序 parsedConditions.value = parseConditions(currentInput.value); - // 检测当前正在编辑的条件索引 - const cursorIndex = findCursorConditionIndex(); - const parts = currentInput.value.split(/[;;]/); - const activeIndex = - cursorIndex >= 0 && cursorIndex < parts.length - ? cursorIndex - : parts.length - 1; - - // 如果正在编辑中间的条件,需要重新排序:将正在编辑的条件移到最后一个位置 - let conditionsToProcess = [...parsedConditions.value]; - if (activeIndex >= 0 && activeIndex < conditionsToProcess.length - 1) { - const [editedCondition] = conditionsToProcess.splice(activeIndex, 1); - conditionsToProcess.push(editedCondition); - } - - // 构建 fieldConditions,参考 buildFieldConditionsPayload 的处理方式 - const fieldConditions = conditionsToProcess + // 构建 fieldConditions,使用最新的条件顺序 + const fieldConditions = parsedConditions.value .filter((condition) => { // 保留有值的条件,或者有字段名但没有值的条件(如 "车型:") return condition.value || (condition.fieldLabel && condition.field); @@ -1527,7 +1586,12 @@ const fetchSearchHints = async (keyword) => { // 从返回的数据中提取字段信息用于"可能属于的字段"下拉框 // 优先根据光标位置确定当前正在编辑的条件,再决定使用哪一段文本 - // 注意:parts、cursorIndex、activeIndex 已在函数开始处声明,这里直接使用 + const parts = currentInput.value.split(/[;;]/); + const cursorIndex = findCursorConditionIndex(); + const activeIndex = + cursorIndex >= 0 && cursorIndex < parts.length + ? cursorIndex + : parts.length - 1; const currentPart = parts[activeIndex]?.trim() || ""; const isEditingExistingField = cursorIndex >= 0 && cursorIndex < parts.length - 1; @@ -1991,40 +2055,26 @@ const syncPreciseConditionsIndex = () => { const buildFieldConditionsPayload = () => { const preciseIndexSet = getPreciseIndexSet(); - // 检测当前正在编辑的条件索引 - const cursorIndex = findCursorConditionIndex(); - const parts = currentInput.value.split(/[;;]/); - const activeIndex = - cursorIndex >= 0 && cursorIndex < parts.length - ? cursorIndex - : parts.length - 1; + // 始终基于最新的 currentInput.value 解析条件,确保使用最新的条件顺序 + const latestConditions = parseConditions(currentInput.value); - // 如果正在编辑中间的条件,需要重新排序:将正在编辑的条件移到最后一个位置 - let conditionsToProcess = [...parsedConditions.value]; - if (activeIndex >= 0 && activeIndex < conditionsToProcess.length - 1) { - const [editedCondition] = conditionsToProcess.splice(activeIndex, 1); - conditionsToProcess.push(editedCondition); - } - - return conditionsToProcess + return latestConditions .filter((condition) => { // 保留有值的条件,或者有字段名但没有值的条件(如 "车型:") return condition.value || (condition.fieldLabel && condition.field); }) .map((condition, index) => { // 计算原始索引(用于精准查询) - const originalIndex = - activeIndex >= 0 && activeIndex < parsedConditions.value.length - 1 - ? index === conditionsToProcess.length - 1 - ? activeIndex - : parsedConditions.value.findIndex( - (c) => - c.fieldLabel === condition.fieldLabel && - c.value === condition.value && - c.field === condition.field - ) - : index; - const queryType = preciseIndexSet.has(originalIndex) ? "EXACT" : "FUZZY"; + // 精准查询条件是基于字段和值匹配的,所以需要找到对应的原始索引 + const originalIndex = parsedConditions.value.findIndex( + (c) => + c.fieldLabel === condition.fieldLabel && + c.value === condition.value && + c.field === condition.field + ); + // 如果找不到原始索引,使用当前索引 + const finalIndex = originalIndex !== -1 ? originalIndex : index; + const queryType = preciseIndexSet.has(finalIndex) ? "EXACT" : "FUZZY"; // 1)字段 + 值:结构化查询 if (condition.valid && condition.field && condition.value) { @@ -2072,22 +2122,10 @@ const buildFieldConditionsPayload = () => { // 为 searchHint 构建 fieldConditions const buildFieldConditionsForHint = () => { - // 检测当前正在编辑的条件索引 - const cursorIndex = findCursorConditionIndex(); - const parts = currentInput.value.split(/[;;]/); - const activeIndex = - cursorIndex >= 0 && cursorIndex < parts.length - ? cursorIndex - : parts.length - 1; + // 始终基于最新的 currentInput.value 解析条件,确保使用最新的条件顺序 + const latestConditions = parseConditions(currentInput.value); - // 如果正在编辑中间的条件,需要重新排序:将正在编辑的条件移到最后一个位置 - let conditionsToProcess = [...parsedConditions.value]; - if (activeIndex >= 0 && activeIndex < conditionsToProcess.length - 1) { - const [editedCondition] = conditionsToProcess.splice(activeIndex, 1); - conditionsToProcess.push(editedCondition); - } - - return conditionsToProcess + return latestConditions .filter((condition) => { // 保留有值的条件,或者有字段名但没有值的条件(如 "车型:") return condition.value || (condition.fieldLabel && condition.field);