diff --git a/src/api/sale/saleRecord/saleRecord.js b/src/api/sale/saleRecord/saleRecord.js index d5517e6..88569f7 100644 --- a/src/api/sale/saleRecord/saleRecord.js +++ b/src/api/sale/saleRecord/saleRecord.js @@ -1,11 +1,11 @@ import request from '@/utils/request' -// 增加模糊搜索耳号 API -export function searchEarNumbers(query) { +// 【修改】增加 sheepfoldId 过滤参数 +export function searchEarNumbers(query, sheepfoldId) { return request({ url: '/saleRecord/saleRecord/searchEarNumbers', method: 'get', - params: { query } + params: { query, sheepfoldId } }) } @@ -82,3 +82,12 @@ export function getSheepInfo(bsManageTags) { params: { bsManageTags } }) } + +// 【新增】查询已销售的羊只耳号(用于查询栏) +export function searchSoldEarNumbers(query) { + return request({ + url: '/saleRecord/saleRecord/searchSoldEarNumbers', + method: 'get', + params: { query } + }) +} diff --git a/src/views/produce/bodyManage/body_measure/index.vue b/src/views/produce/bodyManage/body_measure/index.vue index d4e3688..738b59a 100644 --- a/src/views/produce/bodyManage/body_measure/index.vue +++ b/src/views/produce/bodyManage/body_measure/index.vue @@ -605,12 +605,27 @@ function loadSheepTypeList() { }); } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } function handlePaste() { nextTick(() => handlePasteSubmit()) diff --git a/src/views/produce/bodyManage/body_score/index.vue b/src/views/produce/bodyManage/body_score/index.vue index 8769afa..09075da 100644 --- a/src/views/produce/bodyManage/body_score/index.vue +++ b/src/views/produce/bodyManage/body_score/index.vue @@ -522,12 +522,27 @@ function loadVarietyOptions() { }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } function clearEarNumbers() { diff --git a/src/views/produce/bodyManage/breast_rating/index.vue b/src/views/produce/bodyManage/breast_rating/index.vue index 5da79c5..ac671d6 100644 --- a/src/views/produce/bodyManage/breast_rating/index.vue +++ b/src/views/produce/bodyManage/breast_rating/index.vue @@ -540,12 +540,27 @@ function loadVarietyOptions() { varietyOptions.value = res.rows; }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } function clearEarNumbers() { queryParams.value.manageTagsList = [] diff --git a/src/views/produce/manage_sheep/changeComment/index.vue b/src/views/produce/manage_sheep/changeComment/index.vue index 9d219c9..81b14ce 100644 --- a/src/views/produce/manage_sheep/changeComment/index.vue +++ b/src/views/produce/manage_sheep/changeComment/index.vue @@ -454,13 +454,27 @@ function getSheepfoldOptions() { sheepfoldOptions.value = res.rows }) } -/* 远程搜耳号 */ -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } /* 清空所有耳号 */ diff --git a/src/views/produce/manage_sheep/changeEar/index.vue b/src/views/produce/manage_sheep/changeEar/index.vue index 4479d40..fad47fd 100644 --- a/src/views/produce/manage_sheep/changeEar/index.vue +++ b/src/views/produce/manage_sheep/changeEar/index.vue @@ -497,12 +497,29 @@ function getSheepfoldOptions() { sheepfoldOptions.value = res.rows }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +// 搜索耳号的方法(用于下拉框远程搜索) +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + // 调用API搜索耳号 + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } /* 粘贴事件 */ function handlePaste() { diff --git a/src/views/produce/manage_sheep/changeVariety/index.vue b/src/views/produce/manage_sheep/changeVariety/index.vue index ee4e5e2..7a27815 100644 --- a/src/views/produce/manage_sheep/changeVariety/index.vue +++ b/src/views/produce/manage_sheep/changeVariety/index.vue @@ -467,12 +467,29 @@ function getSheepfoldOptions() { sheepfoldOptions.value = res.rows }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +// 搜索耳号的方法(用于下拉框远程搜索) +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + // 调用API搜索耳号 + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } /* 粘贴事件 */ function handlePaste() { diff --git a/src/views/produce/manage_sheep/trans_group/index.vue b/src/views/produce/manage_sheep/trans_group/index.vue index 3c61176..42742f0 100644 --- a/src/views/produce/manage_sheep/trans_group/index.vue +++ b/src/views/produce/manage_sheep/trans_group/index.vue @@ -629,7 +629,29 @@ function handleQuery() { queryParams.value.pageNum = 1; getList(); } - +// 搜索耳号的方法(用于下拉框远程搜索) +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + + earLoading.value = true + try { + // 调用API搜索耳号 + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + } finally { + earLoading.value = false + } +} //重置搜索框 function resetQuery() { daterangeTransDate.value = []; diff --git a/src/views/produce/manage_sheep/transition_info/index.vue b/src/views/produce/manage_sheep/transition_info/index.vue index bedb059..cde1230 100644 --- a/src/views/produce/manage_sheep/transition_info/index.vue +++ b/src/views/produce/manage_sheep/transition_info/index.vue @@ -769,12 +769,29 @@ function handleDelete(row) { }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +// 搜索耳号的方法(用于下拉框远程搜索) +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + // 调用API搜索耳号 + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } async function handleRanchChange(ranchName) { if (!ranchName) { diff --git a/src/views/produce/other/castrate/index.vue b/src/views/produce/other/castrate/index.vue index 5f42173..41cfc47 100644 --- a/src/views/produce/other/castrate/index.vue +++ b/src/views/produce/other/castrate/index.vue @@ -559,12 +559,27 @@ function filterSheepfold(query) { fold.sheepfoldName.includes(query) ) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } function clearEarNumbers() { queryParams.value.manageTagsList = [] diff --git a/src/views/produce/other/fixHoof/index.vue b/src/views/produce/other/fixHoof/index.vue index 02733a8..acc912b 100644 --- a/src/views/produce/other/fixHoof/index.vue +++ b/src/views/produce/other/fixHoof/index.vue @@ -508,12 +508,27 @@ const fetchTechnicalList = () => { technicalOptions.value = [] }) } -function searchEarNumber(query) { - if (!query) { earOptions.value = []; return } +const searchEarNumber = async (query) => { + if (!query || query.trim() === '') { + earOptions.value = [] + return + } + earLoading.value = true - searchEarNumbers(query.trim()).then(res => { - earOptions.value = res.data || [] - }).finally(() => earLoading.value = false) + try { + const res = await searchEarNumbers(query.trim()) + if (res.code === 200 && Array.isArray(res.data)) { + earOptions.value = res.data + } else { + earOptions.value = [] + } + } catch (error) { + console.error('搜索耳号失败:', error) + earOptions.value = [] + proxy.$modal.msgError('搜索耳号失败') + } finally { + earLoading.value = false + } } function clearEarNumbers() { queryParams.value.manageTagsList = [] diff --git a/src/views/sale/saleRecord/saleRecord/index.vue b/src/views/sale/saleRecord/saleRecord/index.vue index 7b40aba..138d3a2 100644 --- a/src/views/sale/saleRecord/saleRecord/index.vue +++ b/src/views/sale/saleRecord/saleRecord/index.vue @@ -29,10 +29,22 @@ reserve-keyword placeholder="输入耳号搜索,支持多选" :remote-method="searchEarNumberMethod" - :loading="earNumberLoading" + @focus="handleQueryEarNumberFocus" :loading="earNumberLoading" style="width: 100%" clearable > + + - + @change="handleTagChange" + @focus="handleEarNumberFocus"> + + + @@ -455,13 +489,14 @@ import { ref, reactive, toRefs, computed, getCurrentInstance, onMounted } from 'vue' import { listSaleRecord, getSaleRecord, delSaleRecord, addSaleRecord, updateSaleRecord, - getSheepInfo, listSheepInventory, searchEarNumbers + getSheepInfo, listSheepInventory, searchEarNumbers, searchSoldEarNumbers // <- 引入新增的 API } from '@/api/sale/saleRecord/saleRecord' import { listSheepfold_management } from '@/api/fileManagement/sheepfold_management' import { listUser } from '@/api/system/user' import { listCustomer } from '@/api/sale/customer/customer' import { regionData } from 'element-china-area-data' +const formEarNumberLoading = ref(false) const { proxy } = getCurrentInstance() const { disease_type } = proxy.useDict('disease_type') @@ -609,20 +644,35 @@ function handleQueryAreaChange(val) { } } -// 【新增】远程搜索耳号方法 +// 2. 【修改】顶部搜索栏耳号查询方法 function searchEarNumberMethod(query) { - if (query !== '') { - earNumberLoading.value = true - searchEarNumbers(query).then(res => { - earNumberQueryOptions.value = res.data || [] - earNumberLoading.value = false - }).catch(() => { - earNumberQueryOptions.value = [] - earNumberLoading.value = false - }) - } else { + earNumberLoading.value = true + // 这里允许传入空字符串,后端会返回前50条已售耳号 + searchSoldEarNumbers(query).then(res => { + earNumberQueryOptions.value = res.data || [] + earNumberLoading.value = false + }).catch(() => { earNumberQueryOptions.value = [] - } + earNumberLoading.value = false + }) +} + +// 【新增】表单内的耳号远程搜索方法 +function formSearchEarNumberMethod(query) { + formEarNumberLoading.value = true + // 将表单当前选中的羊舍ID传给后端。如果没有选,此处会传 null/undefined,后端将查询全库 + searchEarNumbers(query, form.value.sheepfoldId).then(res => { + earTagOptions.value = res.data || [] + formEarNumberLoading.value = false + }).catch(() => { + earTagOptions.value = [] + formEarNumberLoading.value = false + }) +} + +// 【新增】下拉框获取焦点时,如果还没数据,加载一下默认数据(前50条) +function handleEarNumberFocus() { + formSearchEarNumberMethod('') } // 【新增】移除单个查询耳号 @@ -649,6 +699,8 @@ function handleSheepfoldChange(val) { console.error("获取耳号失败", err) }) } + // 切换羊舍后,立刻用空关键字查一下该羊舍下的耳号,更新下拉列表 + formSearchEarNumberMethod('') } function handleTagChange(tags) { @@ -776,10 +828,23 @@ function handleDelete(row) { }).catch(() => {}) } +// 【修改】导出功能:支持勾选导出与全量导出 function handleExport() { - proxy.download('saleRecord/saleRecord/export', { - ...queryParams.value - }, `saleRecord_${new Date().getTime()}.xlsx`) + // 组装要传给后端的查询参数 + const exportParams = { ...queryParams.value } + let msg = "是否确认导出所有符合查询条件的销售记录?" + + // 如果用户在表格中勾选了数据,就把勾选的ID集合塞进参数里,并改变提示语 + if (ids.value.length > 0) { + exportParams.exportIds = ids.value + msg = `是否确认导出选中的 ${ids.value.length} 条销售记录?` + } + + // 给用户一个明确的二次确认弹窗 + proxy.$modal.confirm(msg).then(() => { + // 确认后调用导出接口,附带时间戳作为文件名 + proxy.download('saleRecord/saleRecord/export', exportParams, `羊只销售记录_${new Date().getTime()}.xlsx`) + }).catch(() => {}) } function cancel() { @@ -804,6 +869,14 @@ function diseaseTypeFormat(row) { // 如果静态选项 label 和 value 一样,则直接返回即可 return row.diseaseType } + +// 3. 【新增】输入框获取焦点时,如果还没数据,自动查询 +function handleQueryEarNumberFocus() { + // 为了防止每次点击都发请求,判断如果没有输入内容且下拉框为空,才去查默认数据 + if (earNumberQueryOptions.value.length === 0) { + searchEarNumberMethod('') + } +}