From e90d6f95444d2277023b81da539d22a0464beb17 Mon Sep 17 00:00:00 2001 From: JenniferW <1627055433@qq.com> Date: Wed, 26 Nov 2025 15:21:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=AF=B9=E6=AF=94bug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/order/intention/search.vue | 100 +++++++++++++++++++++------ 1 file changed, 80 insertions(+), 20 deletions(-) diff --git a/src/views/order/intention/search.vue b/src/views/order/intention/search.vue index 9665ff7..82c3a51 100644 --- a/src/views/order/intention/search.vue +++ b/src/views/order/intention/search.vue @@ -420,6 +420,7 @@ import { compare, } from "@/api/order"; import { ElMessage, ElEmpty, ElDialog } from "element-plus"; +import { Search, RefreshLeft, Microphone } from "@element-plus/icons-vue"; const { proxy } = getCurrentInstance(); const { display_field } = proxy.useDict("display_field"); @@ -461,6 +462,8 @@ const fieldValueMap = ref({}); const allValues = ref([]); const hintTimer = ref(null); const pendingSearchTimer = ref(null); +const differenceTimer = ref(null); +const selectedItems = ref(new Map()); // 语音输入弹窗控制 const showVoicePopup = ref(false); @@ -483,20 +486,20 @@ const currentPageData = computed(() => { }); // 计算选中的商品数量 -const selectedCount = computed(() => { - return filteredData.value.filter((item) => item.selected).length; -}); +const selectedCount = computed(() => selectedItems.value.size); // 选中的商品品号 const selectedProductNumber = computed(() => { - const selected = filteredData.value.find((item) => item.selected); - return selected ? selected.partNumber : ""; + if (selectedItems.value.size !== 1) return ""; + const iterator = selectedItems.value.values().next(); + const first = iterator.value; + return first ? first.partNumber : ""; }); // 对比相关 const compareDialogVisible = ref(false); const selectedCompareList = computed(() => - filteredData.value.filter((i) => i.selected) + Array.from(selectedItems.value.values()) ); // 仅显示不同项的开关 const showOnlyDifferences = ref(false); @@ -540,6 +543,8 @@ const sortedCompareList = computed(() => { const compareTableData = ref([]); const diffFieldKeys = ref(new Set()); +const getItemKey = (item) => item?.id ?? item?.partNumber ?? item?.uuid ?? ""; + const getDictLabel = (dictRef, value) => { if (!dictRef) return null; const list = dictRef.value ?? []; @@ -666,7 +671,7 @@ const addDiffFieldToInput = (field) => { // 触发输入事件和搜索 setTimeout(() => { - handleInput(currentInput.value); + handleInput(currentInput.value, { skipDifference: true }); triggerRealTimeSearch(); // 聚焦输入框并将光标定位到字段后的适当位置 @@ -706,7 +711,7 @@ const handleSemicolon = (e) => { // 延迟处理,确保分号已添加到输入框 setTimeout(() => { // 触发输入事件以更新建议 - handleInput(currentInput.value); + handleInput(currentInput.value, { skipDifference: true }); // 分号输入后触发实时查询 triggerRealTimeSearch(); }, 0); @@ -843,7 +848,7 @@ const triggerConditionSuggestions = (conditionText) => { } } else { // 只有值,没有字段,使用原有逻辑 - handleInput(currentInput.value); + handleInput(currentInput.value, { skipDifference: true }); } }; @@ -1012,6 +1017,14 @@ const updateSuggestionsFromValue = (value) => { const handleInput = (value, options = {}) => { const normalizedValue = value ?? ""; updateSuggestionsFromValue(normalizedValue); + if (!normalizedValue.trim()) { + keyDiffFields.value = []; + showKeyDiffHint.value = false; + if (differenceTimer.value) { + clearTimeout(differenceTimer.value); + differenceTimer.value = null; + } + } if (options.skipFetch) { return; } @@ -1020,6 +1033,9 @@ const handleInput = (value, options = {}) => { if (currentPart) { scheduleSearchHint(currentPart); } + if (!options.skipDifference && normalizedValue.trim()) { + scheduleDifferenceFetch(); + } }; const fetchSearchHints = async (keyword) => { @@ -1032,7 +1048,7 @@ const fetchSearchHints = async (keyword) => { ? res : []; mergeFieldMetadata(hintList); - updateSuggestionsFromValue(currentInput.value, { skipFetch: true }); + updateSuggestionsFromValue(currentInput.value); } catch (error) { console.error("searchHint error:", error); } @@ -1048,6 +1064,16 @@ const scheduleSearchHint = (keyword) => { }, 300); }; +const scheduleDifferenceFetch = () => { + if (differenceTimer.value) { + clearTimeout(differenceTimer.value); + } + if (!currentInput.value.trim()) return; + differenceTimer.value = setTimeout(() => { + fetchDifferenceRecommendations(); + }, 500); +}; + // 选择可能的字段 - 修复问题4 const selectPossibleField = (field) => { // 始终在当前条件上操作,不修改其他条件 @@ -1078,7 +1104,7 @@ const selectPossibleField = (field) => { // 保持建议框显示,允许继续编辑 setTimeout(() => { - handleInput(currentInput.value); + handleInput(currentInput.value, { skipDifference: true }); // 选择字段后触发实时查询 triggerRealTimeSearch(); }, 0); @@ -1174,7 +1200,7 @@ const selectSuggestion = (item) => { // 保持建议框显示,允许继续编辑 setTimeout(() => { - handleInput(currentInput.value); + handleInput(currentInput.value, { skipDifference: true }); // 选择建议项后触发实时查询 triggerRealTimeSearch(); }, 0); @@ -1358,10 +1384,25 @@ const executeSearch = async ({ page = currentPage.value } = {}) => { const pageData = res?.data ?? res ?? {}; const list = pageData?.content ?? []; - filteredData.value = list.map((item) => ({ - ...item, - selected: false, - })); + const mappedList = list.map((item) => { + const key = getItemKey(item); + const isSelected = key ? selectedItems.value.has(key) : false; + return { + ...item, + selected: isSelected, + }; + }); + + const updatedSelectedMap = new Map(selectedItems.value); + mappedList.forEach((item) => { + const key = getItemKey(item); + if (key && updatedSelectedMap.has(key)) { + updatedSelectedMap.set(key, { ...item, selected: true }); + } + }); + selectedItems.value = updatedSelectedMap; + + filteredData.value = mappedList; totalItems.value = pageData?.totalElements ?? list.length; const serverPage = pageData?.number ?? Math.max(page - 1, 0); currentPage.value = serverPage + 1; @@ -1480,6 +1521,7 @@ const handleSearch = async () => { // 清空精准查询条件 preciseConditions.value = []; + selectedItems.value = new Map(); // 执行查询与关键差异词推荐 await executeSearch({ page: 1 }); @@ -1496,6 +1538,7 @@ const triggerRealTimeSearch = () => { if (currentInput.value.trim()) { parsedConditions.value = parseConditions(currentInput.value); scheduleSearchExecution(1); + scheduleDifferenceFetch(); } }; @@ -1509,9 +1552,6 @@ const removeCondition = (index) => { .trim(); parsedConditions.value = parseConditions(currentInput.value); - // 更新关键差异提示 - updateKeyDiffHint(); - // 检查是否有精准查询条件引用了这个索引,如果有则一并删除 const preciseIndex = preciseConditions.value.findIndex( (cond) => cond.originalIndex === index @@ -1522,6 +1562,7 @@ const removeCondition = (index) => { // 重新查询 executeSearch({ page: 1 }); + scheduleDifferenceFetch(); // 重置选中的条件索引 if (selectedConditionIndex.value === index) { @@ -1544,6 +1585,11 @@ const clearAll = () => { // 重置关键差异提示 keyDiffFields.value = []; showKeyDiffHint.value = false; + selectedItems.value = new Map(); + if (differenceTimer.value) { + clearTimeout(differenceTimer.value); + differenceTimer.value = null; + } if (searchInput.value) { searchInput.value.focus(); @@ -1610,7 +1656,21 @@ watch( // 切换选择状态 function toggleSelect(item) { - item.selected = !item.selected; + const key = getItemKey(item); + if (!key) return; + const nextMap = new Map(selectedItems.value); + const isSelected = nextMap.has(key); + + if (isSelected) { + nextMap.delete(key); + item.selected = false; + } else { + const snapshot = { ...item, selected: true }; + nextMap.set(key, snapshot); + item.selected = true; + } + + selectedItems.value = nextMap; } // 打开对比弹窗