繁育多耳号查询
This commit is contained in:
@@ -87,3 +87,11 @@ export function searchHandler(query) {
|
|||||||
params: { query }
|
params: { query }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function searchEarNumbers(query) {
|
||||||
|
return request({
|
||||||
|
url: '/sheep_death/death/search_ear_numbers', // 根据实际路径修改
|
||||||
|
method: 'get',
|
||||||
|
params: { query }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -3,25 +3,100 @@
|
|||||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
|
||||||
|
|
||||||
<el-form-item label="耳号" prop="allEarNumbers">
|
<el-form-item label="耳号" prop="allEarNumbers">
|
||||||
<el-select
|
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||||
v-model="queryParams.allEarNumbers"
|
<!-- 主选择器:不显示已选标签 -->
|
||||||
multiple
|
<el-select
|
||||||
filterable
|
v-model="queryParams.allEarNumbers"
|
||||||
remote
|
multiple
|
||||||
reserve-keyword
|
filterable
|
||||||
placeholder="请输入耳号搜索"
|
remote
|
||||||
:remote-method="searchEarNumber"
|
reserve-keyword
|
||||||
:loading="earNumberLoading"
|
placeholder="输入耳号搜索"
|
||||||
style="width: 240px"
|
:remote-method="searchEarNumber"
|
||||||
clearable
|
:loading="earNumberLoading"
|
||||||
|
allow-create
|
||||||
|
default-first-option
|
||||||
|
collapse-tags
|
||||||
|
:max-collapse-tags="0"
|
||||||
|
style="width: 300px"
|
||||||
|
@change="handleEarNumberChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in earNumberOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 辅助粘贴输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-model="pasteInput"
|
||||||
|
placeholder="或粘贴多个耳号(空格/换行/逗号分隔)"
|
||||||
|
style="width: 300px"
|
||||||
|
@paste="handlePaste"
|
||||||
|
@keyup.enter="handlePasteSubmit"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="handlePasteSubmit" :icon="Plus">添加</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<!-- 耳号计数显示 -->
|
||||||
|
<el-tag
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
type="info"
|
||||||
|
effect="plain"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
已选: {{ queryParams.allEarNumbers.length }} 个
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 清空按钮 -->
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
@click="clearAllEarNumbers"
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
:icon="Delete"
|
||||||
|
>
|
||||||
|
清空全部
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已选耳号展示区域(默认显示2个,可展开) -->
|
||||||
|
<div
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
class="selected-ear-numbers-display"
|
||||||
|
style="margin-top: 10px;"
|
||||||
>
|
>
|
||||||
<el-option
|
<!-- 显示前2个或全部耳号 -->
|
||||||
v-for="item in earNumberOptions"
|
<el-tag
|
||||||
:key="item"
|
v-for="(tag, index) in displayedEarNumbers"
|
||||||
:label="item"
|
:key="tag"
|
||||||
:value="item"
|
closable
|
||||||
/>
|
@close="handleRemoveEarNumber(tag)"
|
||||||
</el-select>
|
style="margin: 4px;"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 展开/收起按钮 -->
|
||||||
|
<el-button
|
||||||
|
v-if="queryParams.allEarNumbers.length > defaultShowCount"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="toggleExpand"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
>
|
||||||
|
{{ isExpanded ? '收起' : `展开剩余 ${queryParams.allEarNumbers.length - defaultShowCount} 个` }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<component :is="isExpanded ? ArrowUp : ArrowDown" />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="是否在群" prop="isInHerd">
|
<el-form-item label="是否在群" prop="isInHerd">
|
||||||
@@ -231,7 +306,29 @@
|
|||||||
|
|
||||||
<script setup name="Weaning_record">
|
<script setup name="Weaning_record">
|
||||||
import { listWeaning_record, getWeaning_record, delWeaning_record, addWeaning_record, updateWeaning_record, getSheepIdByEarNumber, searchEarNumbers } from "@/api/Weaning/weaning_record"
|
import { listWeaning_record, getWeaning_record, delWeaning_record, addWeaning_record, updateWeaning_record, getSheepIdByEarNumber, searchEarNumbers } from "@/api/Weaning/weaning_record"
|
||||||
|
import { ref, computed, nextTick } from 'vue'
|
||||||
|
import { ArrowUp, ArrowDown, Plus, Delete } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const pasteInput = ref('') // 批量粘贴输入框
|
||||||
|
const earNumberOptions = ref([]) // 耳号下拉选项
|
||||||
|
const earNumberLoading = ref(false) // 耳号加载状态
|
||||||
|
const isExpanded = ref(false) // 控制耳号展开/折叠状态
|
||||||
|
const defaultShowCount = 2 // 默认显示的耳号数量
|
||||||
|
|
||||||
|
// 计算属性:控制显示的耳号列表
|
||||||
|
const displayedEarNumbers = computed(() => {
|
||||||
|
if (!queryParams.value.allEarNumbers || queryParams.value.allEarNumbers.length === 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果展开或总数<=2,显示全部;否则只显示前2个
|
||||||
|
if (isExpanded.value || queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
||||||
|
return queryParams.value.allEarNumbers
|
||||||
|
} else {
|
||||||
|
return queryParams.value.allEarNumbers.slice(0, defaultShowCount)
|
||||||
|
}
|
||||||
|
})
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
const weaning_recordList = ref([])
|
const weaning_recordList = ref([])
|
||||||
@@ -245,9 +342,6 @@ const total = ref(0)
|
|||||||
const title = ref("")
|
const title = ref("")
|
||||||
const daterangeTime = ref([]) // 时间范围数组
|
const daterangeTime = ref([]) // 时间范围数组
|
||||||
|
|
||||||
// 远程搜索相关
|
|
||||||
const earNumberOptions = ref([])
|
|
||||||
const earNumberLoading = ref(false)
|
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
form: {},
|
form: {},
|
||||||
@@ -299,27 +393,7 @@ function getList() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 远程搜索耳号 */
|
|
||||||
function searchEarNumber(query) {
|
|
||||||
if (query !== '') {
|
|
||||||
earNumberLoading.value = true
|
|
||||||
searchEarNumbers(query).then(response => {
|
|
||||||
earNumberOptions.value = response.data || []
|
|
||||||
earNumberLoading.value = false
|
|
||||||
}).catch(() => {
|
|
||||||
earNumberOptions.value = []
|
|
||||||
earNumberLoading.value = false
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
earNumberOptions.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 取消按钮
|
|
||||||
function cancel() {
|
|
||||||
open.value = false
|
|
||||||
reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表单重置
|
// 表单重置
|
||||||
function reset() {
|
function reset() {
|
||||||
@@ -347,11 +421,10 @@ function handleQuery() {
|
|||||||
|
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
daterangeTime.value = []
|
queryParams.value.allEarNumbers = [] // 🔥 必须添加
|
||||||
earNumberOptions.value = []
|
earNumberOptions.value = []
|
||||||
|
isExpanded.value = false
|
||||||
proxy.resetForm("queryRef")
|
proxy.resetForm("queryRef")
|
||||||
// 必须手动清空多选数组
|
|
||||||
queryParams.value.allEarNumbers = []
|
|
||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,14 +507,170 @@ function handleExport() {
|
|||||||
}, `weaning_record_${new Date().getTime()}.xlsx`)
|
}, `weaning_record_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 处理粘贴事件 */
|
||||||
|
function handlePaste(event) {
|
||||||
|
nextTick(() => {
|
||||||
|
handlePasteSubmit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理粘贴内容提交 */
|
||||||
|
function handlePasteSubmit() {
|
||||||
|
if (!pasteInput.value || pasteInput.value.trim() === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持多种分隔符: 空格、换行、逗号、制表符
|
||||||
|
const separators = /[\s,,\n\r\t]+/
|
||||||
|
const earNumbers = pasteInput.value
|
||||||
|
.trim()
|
||||||
|
.split(separators)
|
||||||
|
.filter(item => item.trim() !== '')
|
||||||
|
.map(item => item.trim())
|
||||||
|
|
||||||
|
if (earNumbers.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去重并添加到已选列表
|
||||||
|
const existingSet = new Set(queryParams.value.allEarNumbers || [])
|
||||||
|
const newEarNumbers = []
|
||||||
|
const duplicates = []
|
||||||
|
|
||||||
|
earNumbers.forEach(earNumber => {
|
||||||
|
if (!existingSet.has(earNumber)) {
|
||||||
|
newEarNumbers.push(earNumber)
|
||||||
|
existingSet.add(earNumber)
|
||||||
|
} else {
|
||||||
|
duplicates.push(earNumber)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加新耳号
|
||||||
|
if (newEarNumbers.length > 0) {
|
||||||
|
queryParams.value.allEarNumbers = [
|
||||||
|
...(queryParams.value.allEarNumbers || []),
|
||||||
|
...newEarNumbers
|
||||||
|
]
|
||||||
|
|
||||||
|
const message = `成功添加 ${newEarNumbers.length} 个耳号,当前共 ${queryParams.value.allEarNumbers.length} 个` +
|
||||||
|
(duplicates.length > 0 ? `,已忽略 ${duplicates.length} 个重复耳号` : '')
|
||||||
|
|
||||||
|
proxy.$modal.msgSuccess(message)
|
||||||
|
} else if (duplicates.length > 0) {
|
||||||
|
proxy.$modal.msgWarning(`所有耳号均已存在,当前共 ${queryParams.value.allEarNumbers.length} 个`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空输入框
|
||||||
|
pasteInput.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 远程搜索耳号 */
|
||||||
|
function searchEarNumber(query) {
|
||||||
|
if (query !== '') {
|
||||||
|
earNumberLoading.value = true
|
||||||
|
|
||||||
|
const queries = query.trim().split(/[\s,,]+/).filter(q => q)
|
||||||
|
|
||||||
|
if (queries.length === 1) {
|
||||||
|
// 单个耳号模糊搜索
|
||||||
|
searchEarNumbers(query).then(response => {
|
||||||
|
earNumberOptions.value = response.data || []
|
||||||
|
earNumberLoading.value = false
|
||||||
|
}).catch(() => {
|
||||||
|
earNumberOptions.value = []
|
||||||
|
earNumberLoading.value = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 多个耳号直接作为选项
|
||||||
|
earNumberOptions.value = queries
|
||||||
|
earNumberLoading.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
earNumberOptions.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 耳号选择变化处理 */
|
||||||
|
function handleEarNumberChange(value) {
|
||||||
|
queryParams.value.allEarNumbers = [...new Set(value)]
|
||||||
|
console.log(`已选择 ${queryParams.value.allEarNumbers.length} 个耳号:`, queryParams.value.allEarNumbers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 切换展开/收起状态 */
|
||||||
|
function toggleExpand() {
|
||||||
|
isExpanded.value = !isExpanded.value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 移除单个耳号 */
|
||||||
|
function handleRemoveEarNumber(tag) {
|
||||||
|
const index = queryParams.value.allEarNumbers.indexOf(tag)
|
||||||
|
if (index > -1) {
|
||||||
|
queryParams.value.allEarNumbers.splice(index, 1)
|
||||||
|
proxy.$modal.msgSuccess('已移除该耳号')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果删除后剩余<=2个,自动收起
|
||||||
|
if (queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
||||||
|
isExpanded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清空所有耳号 */
|
||||||
|
function clearAllEarNumbers() {
|
||||||
|
proxy.$modal.confirm('确定要清空所有已选择的耳号吗?').then(() => {
|
||||||
|
queryParams.value.allEarNumbers = []
|
||||||
|
pasteInput.value = ''
|
||||||
|
earNumberOptions.value = []
|
||||||
|
isExpanded.value = false // 重置展开状态
|
||||||
|
proxy.$modal.msgSuccess('已清空所有耳号')
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.app-container {
|
/* 已选耳号展示区样式 */
|
||||||
padding: 20px;
|
.selected-ear-numbers-display {
|
||||||
|
max-height: 150px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px dashed #dcdfe6;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
}
|
}
|
||||||
.mb8 {
|
|
||||||
margin-bottom: 8px;
|
.selected-ear-numbers-display::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #dcdfe6;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display::-webkit-scrollbar-track {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display .el-tag {
|
||||||
|
margin: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display .el-tag:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏 el-select 的下拉箭头(可选) */
|
||||||
|
:deep(.el-select__caret) {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -369,7 +369,8 @@
|
|||||||
<el-row :gutter="20" class="lamb-form-content">
|
<el-row :gutter="20" class="lamb-form-content">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item :label="`羔羊耳号`" :prop="`lambForms.${index}.lambEarNumber`">
|
<el-form-item :label="`羔羊耳号`" :prop="`lambForms.${index}.lambEarNumber`">
|
||||||
<el-input v-model="lamb.lambEarNumber" placeholder="请输入羔羊耳号" />
|
<el-input v-model="lamb.lambEarNumber" placeholder="请输入羔羊耳号"
|
||||||
|
@input="handleLambEarNumberInput(index)"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -567,6 +568,64 @@ const data = reactive({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 品种 ID 常量定义 (对应 ScEmbryoFlushServiceImpl)
|
||||||
|
const VARIETY_IDS = {
|
||||||
|
HUYANG: 1, // 湖羊
|
||||||
|
DONGFULISHENG: 2, // 东佛里生
|
||||||
|
HUIJIAO: 3, // 回交
|
||||||
|
JIZA_1: 4, // 级杂一代
|
||||||
|
JIZA_2: 5, // 级杂二代
|
||||||
|
JIZA_3: 6, // 级杂三代
|
||||||
|
SHIDAI_1: 7, // 一世代
|
||||||
|
SHIDAI_2: 8, // 二世代
|
||||||
|
SHIDAI_3: 9, // 三世代
|
||||||
|
SHIDAI_4: 10 // 四世代
|
||||||
|
};
|
||||||
|
|
||||||
|
/** * 品种计算核心逻辑 (参考后端 calculateEmbryoVarietyById)
|
||||||
|
* @param {number} maleId 公羊品种ID
|
||||||
|
* @param {number} femaleId 母羊品种ID
|
||||||
|
* @returns {number|null} 羔羊品种ID
|
||||||
|
*/
|
||||||
|
function calculateLambBreedId(maleId, femaleId) {
|
||||||
|
if (!maleId || !femaleId) return null;
|
||||||
|
|
||||||
|
// 湖羊 x 湖羊 -> 湖羊
|
||||||
|
if (maleId === VARIETY_IDS.HUYANG && femaleId === VARIETY_IDS.HUYANG) return VARIETY_IDS.HUYANG;
|
||||||
|
|
||||||
|
// 东佛里生 x 东佛里生 -> 东佛里生
|
||||||
|
if (maleId === VARIETY_IDS.DONGFULISHENG && femaleId === VARIETY_IDS.DONGFULISHENG) return VARIETY_IDS.DONGFULISHENG;
|
||||||
|
|
||||||
|
// 东佛里生 x 湖羊 -> 级杂一代
|
||||||
|
if (maleId === VARIETY_IDS.DONGFULISHENG && femaleId === VARIETY_IDS.HUYANG) return VARIETY_IDS.JIZA_1;
|
||||||
|
|
||||||
|
// 东佛里生 x 级杂一代 -> 级杂二代
|
||||||
|
if (maleId === VARIETY_IDS.DONGFULISHENG && femaleId === VARIETY_IDS.JIZA_1) return VARIETY_IDS.JIZA_2;
|
||||||
|
|
||||||
|
// 东佛里生 x 级杂二代 -> 级杂三代
|
||||||
|
if (maleId === VARIETY_IDS.DONGFULISHENG && femaleId === VARIETY_IDS.JIZA_2) return VARIETY_IDS.JIZA_3;
|
||||||
|
|
||||||
|
// 东佛里生 x 级杂三代 -> 东佛里生
|
||||||
|
if (maleId === VARIETY_IDS.DONGFULISHENG && femaleId === VARIETY_IDS.JIZA_3) return VARIETY_IDS.DONGFULISHENG;
|
||||||
|
|
||||||
|
// 湖羊 x 级杂三代 -> 回交
|
||||||
|
if (maleId === VARIETY_IDS.HUYANG && femaleId === VARIETY_IDS.JIZA_3) return VARIETY_IDS.HUIJIAO;
|
||||||
|
|
||||||
|
// 湖羊 x 回交 -> 回交
|
||||||
|
if (maleId === VARIETY_IDS.HUYANG && femaleId === VARIETY_IDS.HUIJIAO) return VARIETY_IDS.HUIJIAO;
|
||||||
|
|
||||||
|
// 世代计算规则
|
||||||
|
const isMaleCapable = (maleId >= 3 && maleId <= 10);
|
||||||
|
if (isMaleCapable) {
|
||||||
|
if (femaleId === VARIETY_IDS.JIZA_2) return VARIETY_IDS.SHIDAI_1;
|
||||||
|
if (femaleId === VARIETY_IDS.SHIDAI_1) return VARIETY_IDS.SHIDAI_2;
|
||||||
|
if (femaleId === VARIETY_IDS.SHIDAI_2) return VARIETY_IDS.SHIDAI_3;
|
||||||
|
if (femaleId === VARIETY_IDS.SHIDAI_3) return VARIETY_IDS.SHIDAI_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data)
|
const { queryParams, form, rules } = toRefs(data)
|
||||||
|
|
||||||
// 新增:获取技术员列表
|
// 新增:获取技术员列表
|
||||||
@@ -767,11 +826,8 @@ function handleEarNumberInput() {
|
|||||||
|
|
||||||
/** 母羊耳号失焦处理 - 自动查询配种信息 */
|
/** 母羊耳号失焦处理 - 自动查询配种信息 */
|
||||||
function handleEarNumberBlur() {
|
function handleEarNumberBlur() {
|
||||||
const earNumber = form.value.femaleEarNumber
|
const earNumber = form.value.femaleEarNumber;
|
||||||
if (!earNumber || earNumber.trim() === '') {
|
if (!earNumber || earNumber.trim() === '') return;
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用API查询配种信息
|
// 调用API查询配种信息
|
||||||
getBreedingInfo(earNumber.trim()).then(response => {
|
getBreedingInfo(earNumber.trim()).then(response => {
|
||||||
if (response.code === 200 && response.data) {
|
if (response.code === 200 && response.data) {
|
||||||
@@ -784,7 +840,19 @@ function handleEarNumberBlur() {
|
|||||||
form.value.breedingDate = breedingData.breeding_date
|
form.value.breedingDate = breedingData.breeding_date
|
||||||
form.value.pregnancyDays = breedingData.pregnancy_days
|
form.value.pregnancyDays = breedingData.pregnancy_days
|
||||||
form.value.technician = breedingData.technician || ''
|
form.value.technician = breedingData.technician || ''
|
||||||
|
const mVariety = varietyList.value.find(v => v.variety === breedingData.male_breed);
|
||||||
|
const fVariety = varietyList.value.find(v => v.variety === breedingData.female_breed);
|
||||||
|
|
||||||
|
// 临时存储这些信息,用于初始化羔羊列表
|
||||||
|
form.value._calculatedLambBreedId = calculateLambBreedId(mVariety?.id, fVariety?.id);
|
||||||
|
form.value._fatherLineage = breedingData.male_lineage || ''; // 确保后端返回了家系字段
|
||||||
|
if (lambForms.value && lambForms.value.length > 0) {
|
||||||
|
lambForms.value.forEach(lamb => {
|
||||||
|
lamb.lineage = form.value._fatherLineage;
|
||||||
|
lamb.lambBreed = form.value._calculatedLambBreedId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
proxy.$modal.msgSuccess("已自动匹配父母品种及家系信息");
|
||||||
proxy.$modal.msgSuccess("已自动填充配种信息")
|
proxy.$modal.msgSuccess("已自动填充配种信息")
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgWarning(response.msg || "未找到该母羊的配种记录")
|
proxy.$modal.msgWarning(response.msg || "未找到该母羊的配种记录")
|
||||||
@@ -801,6 +869,7 @@ function handleEarNumberBlur() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 查询产羔记录列表 */
|
/** 查询产羔记录列表 */
|
||||||
function getList() {
|
function getList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -886,21 +955,21 @@ function handleUpdate(row) {
|
|||||||
|
|
||||||
/** 产羔数量变化处理 */
|
/** 产羔数量变化处理 */
|
||||||
function handleLambsBornChange() {
|
function handleLambsBornChange() {
|
||||||
const count = parseInt(form.value.lambsBorn) || 0
|
const count = parseInt(form.value.lambsBorn) || 0;
|
||||||
if (count > 0 && count <= 10) { // 限制最大数量
|
if (count > 0 && count <= 10) {
|
||||||
showLambForms.value = true
|
showLambForms.value = true;
|
||||||
lambForms.value = Array.from({ length: count }, (_, index) => ({
|
lambForms.value = Array.from({ length: count }, () => ({
|
||||||
lambEarNumber: '',
|
lambEarNumber: '',
|
||||||
gender: '',
|
gender: '',
|
||||||
isRetained: false,
|
isRetained: true, // 默认留养
|
||||||
birthWeight: null,
|
birthWeight: null,
|
||||||
lambBreed: null,
|
lambBreed: form.value._calculatedLambBreedId, // 自动填充计算出的品种
|
||||||
lineage: '',
|
lineage: form.value._fatherLineage, // 随父亲家系
|
||||||
birthday: ''
|
birthday: form.value.createTime || new Date().toISOString().split('T')[0] // 随产羔日期
|
||||||
}))
|
}));
|
||||||
} else {
|
} else {
|
||||||
showLambForms.value = false
|
showLambForms.value = false;
|
||||||
lambForms.value = []
|
lambForms.value = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,6 +1036,24 @@ function submitForm() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
/** 监听羔羊耳号输入,自动识别性别 */
|
||||||
|
function handleLambEarNumberInput(index) {
|
||||||
|
const lamb = lambForms.value[index]
|
||||||
|
const earNumber = lamb.lambEarNumber
|
||||||
|
|
||||||
|
// 确保耳号长度至少有2位
|
||||||
|
if (earNumber && earNumber.length >= 2) {
|
||||||
|
// 获取第二个字符并转大写
|
||||||
|
const secondChar = earNumber.charAt(1).toUpperCase()
|
||||||
|
|
||||||
|
if (secondChar === 'F') {
|
||||||
|
lamb.gender = 'female' // 对应 <el-option label="母" value="female">
|
||||||
|
} else if (secondChar === 'M') {
|
||||||
|
lamb.gender = 'male' // 对应 <el-option label="公" value="male">
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
|
|||||||
@@ -2,27 +2,101 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
|
||||||
|
|
||||||
<el-form-item label="耳号" prop="manageTagsList">
|
<el-form-item label="母羊耳号" prop="allEarNumbers">
|
||||||
<el-select
|
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||||
v-model="queryParams.manageTagsList"
|
<!-- 主选择器:不显示已选标签 -->
|
||||||
multiple
|
<el-select
|
||||||
filterable
|
v-model="queryParams.allEarNumbers"
|
||||||
remote
|
multiple
|
||||||
reserve-keyword
|
filterable
|
||||||
placeholder="请输入耳号搜索"
|
remote
|
||||||
:remote-method="searchEarNumber"
|
reserve-keyword
|
||||||
:loading="earNumberLoading"
|
placeholder="输入耳号搜索"
|
||||||
style="width: 240px"
|
:remote-method="searchEarNumber"
|
||||||
clearable
|
:loading="earNumberLoading"
|
||||||
@change="handleQuery"
|
allow-create
|
||||||
|
default-first-option
|
||||||
|
collapse-tags
|
||||||
|
:max-collapse-tags="0"
|
||||||
|
style="width: 300px"
|
||||||
|
@change="handleEarNumberChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in earNumberOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 辅助粘贴输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-model="pasteInput"
|
||||||
|
placeholder="或粘贴多个耳号(空格/换行/逗号分隔)"
|
||||||
|
style="width: 300px"
|
||||||
|
@paste="handlePaste"
|
||||||
|
@keyup.enter="handlePasteSubmit"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="handlePasteSubmit" :icon="Plus">添加</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<!-- 耳号计数显示 -->
|
||||||
|
<el-tag
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
type="info"
|
||||||
|
effect="plain"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
已选: {{ queryParams.allEarNumbers.length }} 个
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 清空按钮 -->
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
@click="clearAllEarNumbers"
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
:icon="Delete"
|
||||||
|
>
|
||||||
|
清空全部
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已选耳号展示区域(默认显示2个,可展开) -->
|
||||||
|
<div
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
class="selected-ear-numbers-display"
|
||||||
|
style="margin-top: 10px;"
|
||||||
>
|
>
|
||||||
<el-option
|
<!-- 显示前2个或全部耳号 -->
|
||||||
v-for="item in earNumberOptions"
|
<el-tag
|
||||||
:key="item"
|
v-for="(tag, index) in displayedEarNumbers"
|
||||||
:label="item"
|
:key="tag"
|
||||||
:value="item"
|
closable
|
||||||
/>
|
@close="handleRemoveEarNumber(tag)"
|
||||||
</el-select>
|
style="margin: 4px;"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 展开/收起按钮 -->
|
||||||
|
<el-button
|
||||||
|
v-if="queryParams.allEarNumbers.length > defaultShowCount"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="toggleExpand"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
>
|
||||||
|
{{ isExpanded ? '收起' : `展开剩余 ${queryParams.allEarNumbers.length - defaultShowCount} 个` }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<component :is="isExpanded ? ArrowUp : ArrowDown" />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="干奶日期" style="width: 308px">
|
<el-form-item label="干奶日期" style="width: 308px">
|
||||||
@@ -180,6 +254,29 @@ import { getUserByPost } from '@/api/common/user' // 新增引入
|
|||||||
import { listUser } from "@/api/system/user";
|
import { listUser } from "@/api/system/user";
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
|
import { ref, computed, nextTick } from 'vue'
|
||||||
|
import { ArrowUp, ArrowDown, Plus, Delete } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const pasteInput = ref('') // 批量粘贴输入框
|
||||||
|
const earNumberOptions = ref([]) // 耳号下拉选项
|
||||||
|
const earNumberLoading = ref(false) // 耳号加载状态
|
||||||
|
const isExpanded = ref(false) // 控制耳号展开/折叠状态
|
||||||
|
const defaultShowCount = 2 // 默认显示的耳号数量
|
||||||
|
|
||||||
|
// 计算属性:控制显示的耳号列表
|
||||||
|
const displayedEarNumbers = computed(() => {
|
||||||
|
if (!queryParams.value.allEarNumbers || queryParams.value.allEarNumbers.length === 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果展开或总数<=2,显示全部;否则只显示前2个
|
||||||
|
if (isExpanded.value || queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
||||||
|
return queryParams.value.allEarNumbers
|
||||||
|
} else {
|
||||||
|
return queryParams.value.allEarNumbers.slice(0, defaultShowCount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
@@ -196,10 +293,6 @@ const dateRange = ref([])
|
|||||||
const sheepfoldOptions = ref([])
|
const sheepfoldOptions = ref([])
|
||||||
const userOptions = ref([])
|
const userOptions = ref([])
|
||||||
|
|
||||||
// 耳号搜索变量
|
|
||||||
const earNumberLoading = ref(false)
|
|
||||||
const earNumberOptions = ref([])
|
|
||||||
|
|
||||||
// 新增:技术员选项
|
// 新增:技术员选项
|
||||||
const technicalOptions = ref([])
|
const technicalOptions = ref([])
|
||||||
|
|
||||||
@@ -209,6 +302,7 @@ const data = reactive({
|
|||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
manageTags: null,
|
manageTags: null,
|
||||||
|
allEarNumbers: [], // ✅ 添加这一行!
|
||||||
manageTagsList: [],
|
manageTagsList: [],
|
||||||
technicianList: [], // 技术员多选列表
|
technicianList: [], // 技术员多选列表
|
||||||
tecahnician: null, // 兼容旧字段
|
tecahnician: null, // 兼容旧字段
|
||||||
@@ -244,21 +338,122 @@ const fetchTechnicalList = () => {
|
|||||||
|
|
||||||
/** 远程搜索耳号 */
|
/** 远程搜索耳号 */
|
||||||
function searchEarNumber(query) {
|
function searchEarNumber(query) {
|
||||||
if (query) {
|
if (query !== '') {
|
||||||
earNumberLoading.value = true;
|
earNumberLoading.value = true
|
||||||
searchEarNumbers(query).then(res => {
|
|
||||||
earNumberLoading.value = false;
|
const queries = query.trim().split(/[\s,,]+/).filter(q => q)
|
||||||
const list = res.data || res.msg || res;
|
|
||||||
earNumberOptions.value = Array.isArray(list) ? list : [];
|
if (queries.length === 1) {
|
||||||
}).catch(err => {
|
// 单个耳号模糊搜索
|
||||||
earNumberLoading.value = false;
|
searchEarNumbers(query).then(response => {
|
||||||
earNumberOptions.value = [];
|
earNumberOptions.value = response.data || []
|
||||||
});
|
earNumberLoading.value = false
|
||||||
|
}).catch(() => {
|
||||||
|
earNumberOptions.value = []
|
||||||
|
earNumberLoading.value = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 多个耳号直接作为选项
|
||||||
|
earNumberOptions.value = queries
|
||||||
|
earNumberLoading.value = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
earNumberOptions.value = [];
|
earNumberOptions.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 处理粘贴事件 */
|
||||||
|
function handlePaste(event) {
|
||||||
|
nextTick(() => {
|
||||||
|
handlePasteSubmit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理粘贴内容提交 */
|
||||||
|
function handlePasteSubmit() {
|
||||||
|
if (!pasteInput.value || pasteInput.value.trim() === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持多种分隔符: 空格、换行、逗号、制表符
|
||||||
|
const separators = /[\s,,\n\r\t]+/
|
||||||
|
const earNumbers = pasteInput.value
|
||||||
|
.trim()
|
||||||
|
.split(separators)
|
||||||
|
.filter(item => item.trim() !== '')
|
||||||
|
.map(item => item.trim())
|
||||||
|
|
||||||
|
if (earNumbers.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去重并添加到已选列表
|
||||||
|
const existingSet = new Set(queryParams.value.allEarNumbers || [])
|
||||||
|
const newEarNumbers = []
|
||||||
|
const duplicates = []
|
||||||
|
|
||||||
|
earNumbers.forEach(earNumber => {
|
||||||
|
if (!existingSet.has(earNumber)) {
|
||||||
|
newEarNumbers.push(earNumber)
|
||||||
|
existingSet.add(earNumber)
|
||||||
|
} else {
|
||||||
|
duplicates.push(earNumber)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加新耳号
|
||||||
|
if (newEarNumbers.length > 0) {
|
||||||
|
queryParams.value.allEarNumbers = [
|
||||||
|
...(queryParams.value.allEarNumbers || []),
|
||||||
|
...newEarNumbers
|
||||||
|
]
|
||||||
|
|
||||||
|
const message = `成功添加 ${newEarNumbers.length} 个耳号,当前共 ${queryParams.value.allEarNumbers.length} 个` +
|
||||||
|
(duplicates.length > 0 ? `,已忽略 ${duplicates.length} 个重复耳号` : '')
|
||||||
|
|
||||||
|
proxy.$modal.msgSuccess(message)
|
||||||
|
} else if (duplicates.length > 0) {
|
||||||
|
proxy.$modal.msgWarning(`所有耳号均已存在,当前共 ${queryParams.value.allEarNumbers.length} 个`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空输入框
|
||||||
|
pasteInput.value = ''
|
||||||
|
}
|
||||||
|
/** 耳号选择变化处理 */
|
||||||
|
function handleEarNumberChange(value) {
|
||||||
|
queryParams.value.allEarNumbers = [...new Set(value)]
|
||||||
|
console.log(`已选择 ${queryParams.value.allEarNumbers.length} 个耳号:`, queryParams.value.allEarNumbers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 切换展开/收起状态 */
|
||||||
|
function toggleExpand() {
|
||||||
|
isExpanded.value = !isExpanded.value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 移除单个耳号 */
|
||||||
|
function handleRemoveEarNumber(tag) {
|
||||||
|
const index = queryParams.value.allEarNumbers.indexOf(tag)
|
||||||
|
if (index > -1) {
|
||||||
|
queryParams.value.allEarNumbers.splice(index, 1)
|
||||||
|
proxy.$modal.msgSuccess('已移除该耳号')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果删除后剩余<=2个,自动收起
|
||||||
|
if (queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
||||||
|
isExpanded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清空所有耳号 */
|
||||||
|
function clearAllEarNumbers() {
|
||||||
|
proxy.$modal.confirm('确定要清空所有已选择的耳号吗?').then(() => {
|
||||||
|
queryParams.value.allEarNumbers = []
|
||||||
|
pasteInput.value = ''
|
||||||
|
earNumberOptions.value = []
|
||||||
|
isExpanded.value = false // 重置展开状态
|
||||||
|
proxy.$modal.msgSuccess('已清空所有耳号')
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
/** 查询干奶记录列表 */
|
/** 查询干奶记录列表 */
|
||||||
function getList() {
|
function getList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -314,14 +509,6 @@ function reset() {
|
|||||||
proxy.resetForm("drymilkRef")
|
proxy.resetForm("drymilkRef")
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetQuery() {
|
|
||||||
dateRange.value = []
|
|
||||||
queryParams.value.manageTagsList = []
|
|
||||||
queryParams.value.technicianList = []
|
|
||||||
earNumberOptions.value = []
|
|
||||||
proxy.resetForm("queryRef")
|
|
||||||
handleQuery()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
queryParams.value.pageNum = 1
|
queryParams.value.pageNum = 1
|
||||||
@@ -398,10 +585,60 @@ function handleExport() {
|
|||||||
}
|
}
|
||||||
proxy.download('drymilk/drymilk/export', params, `drymilk_${new Date().getTime()}.xlsx`)
|
proxy.download('drymilk/drymilk/export', params, `drymilk_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
queryParams.value.allEarNumbers = [] // 🔥 必须添加
|
||||||
|
earNumberOptions.value = []
|
||||||
|
isExpanded.value = false
|
||||||
|
proxy.resetForm("queryRef")
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
// 初始化
|
// 初始化
|
||||||
getList()
|
getList()
|
||||||
getSheepfoldList()
|
getSheepfoldList()
|
||||||
getUserList()
|
getUserList()
|
||||||
fetchTechnicalList() // 初始化加载技术员列表
|
fetchTechnicalList() // 初始化加载技术员列表
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 已选耳号展示区样式 */
|
||||||
|
.selected-ear-numbers-display {
|
||||||
|
max-height: 150px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px dashed #dcdfe6;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #dcdfe6;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display::-webkit-scrollbar-track {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display .el-tag {
|
||||||
|
margin: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-ear-numbers-display .el-tag:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏 el-select 的下拉箭头(可选) */
|
||||||
|
:deep(.el-select__caret) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,28 +2,101 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px">
|
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px">
|
||||||
|
|
||||||
<el-form-item label="管理耳号" prop="manageTagsList">
|
<el-form-item label="耳号" prop="allEarNumbers">
|
||||||
<el-select
|
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||||
v-model="queryParams.manageTagsList"
|
<!-- 主选择器:不显示已选标签 -->
|
||||||
multiple
|
<el-select
|
||||||
filterable
|
v-model="queryParams.allEarNumbers"
|
||||||
remote
|
multiple
|
||||||
reserve-keyword
|
filterable
|
||||||
placeholder="请输入耳号"
|
remote
|
||||||
:remote-method="remoteSearchEarNo"
|
reserve-keyword
|
||||||
:loading="loadingSearch"
|
placeholder="输入耳号搜索"
|
||||||
allow-create
|
:remote-method="searchEarNumber"
|
||||||
default-first-option
|
:loading="earNumberLoading"
|
||||||
clearable
|
allow-create
|
||||||
style="width: 240px"
|
default-first-option
|
||||||
|
collapse-tags
|
||||||
|
:max-collapse-tags="0"
|
||||||
|
style="width: 300px"
|
||||||
|
@change="handleEarNumberChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in earNumberOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 辅助粘贴输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-model="pasteInput"
|
||||||
|
placeholder="或粘贴多个耳号(空格/换行/逗号分隔)"
|
||||||
|
style="width: 300px"
|
||||||
|
@paste="handlePaste"
|
||||||
|
@keyup.enter="handlePasteSubmit"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="handlePasteSubmit" :icon="Plus">添加</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<!-- 耳号计数显示 -->
|
||||||
|
<el-tag
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
type="info"
|
||||||
|
effect="plain"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
已选: {{ queryParams.allEarNumbers.length }} 个
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 清空按钮 -->
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
@click="clearAllEarNumbers"
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
:icon="Delete"
|
||||||
|
>
|
||||||
|
清空全部
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已选耳号展示区域(默认显示2个,可展开) -->
|
||||||
|
<div
|
||||||
|
v-if="queryParams.allEarNumbers && queryParams.allEarNumbers.length > 0"
|
||||||
|
class="selected-ear-numbers-display"
|
||||||
|
style="margin-top: 10px;"
|
||||||
>
|
>
|
||||||
<el-option
|
<!-- 显示前2个或全部耳号 -->
|
||||||
v-for="item in earNoOptions"
|
<el-tag
|
||||||
:key="item"
|
v-for="(tag, index) in displayedEarNumbers"
|
||||||
:label="item"
|
:key="tag"
|
||||||
:value="item"
|
closable
|
||||||
/>
|
@close="handleRemoveEarNumber(tag)"
|
||||||
</el-select>
|
style="margin: 4px;"
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
|
||||||
|
<!-- 展开/收起按钮 -->
|
||||||
|
<el-button
|
||||||
|
v-if="queryParams.allEarNumbers.length > defaultShowCount"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="toggleExpand"
|
||||||
|
style="margin-left: 8px;"
|
||||||
|
>
|
||||||
|
{{ isExpanded ? '收起' : `展开剩余 ${queryParams.allEarNumbers.length - defaultShowCount} 个` }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<component :is="isExpanded ? ArrowUp : ArrowDown" />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="死亡日期" prop="deathDateRange">
|
<el-form-item label="死亡日期" prop="deathDateRange">
|
||||||
@@ -379,11 +452,15 @@ import {
|
|||||||
getSheepInfo,
|
getSheepInfo,
|
||||||
getDiseaseTree,
|
getDiseaseTree,
|
||||||
searchEarNo,
|
searchEarNo,
|
||||||
|
searchEarNumbers,
|
||||||
// searchTechnician, // 移除旧的远程搜索接口
|
// searchTechnician, // 移除旧的远程搜索接口
|
||||||
// searchHandler // 移除旧的远程搜索接口
|
// searchHandler // 移除旧的远程搜索接口
|
||||||
} from "@/api/sheep_death/death"
|
} from "@/api/sheep_death/death"
|
||||||
import { getUserByPost } from '@/api/common/user' // 新增引入
|
import { getUserByPost } from '@/api/common/user' // 新增引入
|
||||||
|
|
||||||
|
import { ref, computed, nextTick } from 'vue'
|
||||||
|
import { ArrowUp, ArrowDown, Plus, Delete } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const pasteInput = ref('') // 批量粘贴输入框
|
const pasteInput = ref('') // 批量粘贴输入框
|
||||||
const earNumberOptions = ref([]) // 耳号下拉选项
|
const earNumberOptions = ref([]) // 耳号下拉选项
|
||||||
@@ -391,9 +468,6 @@ const earNumberLoading = ref(false) // 耳号加载状态
|
|||||||
const isExpanded = ref(false) // 控制耳号展开/折叠状态
|
const isExpanded = ref(false) // 控制耳号展开/折叠状态
|
||||||
const defaultShowCount = 2 // 默认显示的耳号数量
|
const defaultShowCount = 2 // 默认显示的耳号数量
|
||||||
|
|
||||||
// 新增:技术员选项
|
|
||||||
const technicalOptions = ref([])
|
|
||||||
|
|
||||||
// 计算属性:控制显示的耳号列表
|
// 计算属性:控制显示的耳号列表
|
||||||
const displayedEarNumbers = computed(() => {
|
const displayedEarNumbers = computed(() => {
|
||||||
if (!queryParams.value.allEarNumbers || queryParams.value.allEarNumbers.length === 0) {
|
if (!queryParams.value.allEarNumbers || queryParams.value.allEarNumbers.length === 0) {
|
||||||
@@ -407,6 +481,10 @@ const displayedEarNumbers = computed(() => {
|
|||||||
return queryParams.value.allEarNumbers.slice(0, defaultShowCount)
|
return queryParams.value.allEarNumbers.slice(0, defaultShowCount)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 新增:技术员选项
|
||||||
|
const technicalOptions = ref([])
|
||||||
|
|
||||||
const {proxy} = getCurrentInstance()
|
const {proxy} = getCurrentInstance()
|
||||||
// 获取字典数据
|
// 获取字典数据
|
||||||
const { sys_sheep_type } = proxy.useDict("sys_sheep_type");
|
const { sys_sheep_type } = proxy.useDict("sys_sheep_type");
|
||||||
@@ -483,56 +561,6 @@ function handlePaste(event) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理粘贴内容提交 */
|
|
||||||
function handlePasteSubmit() {
|
|
||||||
if (!pasteInput.value || pasteInput.value.trim() === '') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 支持多种分隔符: 空格、换行、逗号、制表符
|
|
||||||
const separators = /[\s,,\n\r\t]+/
|
|
||||||
const earNumbers = pasteInput.value
|
|
||||||
.trim()
|
|
||||||
.split(separators)
|
|
||||||
.filter(item => item.trim() !== '')
|
|
||||||
.map(item => item.trim())
|
|
||||||
|
|
||||||
if (earNumbers.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 去重并添加到已选列表
|
|
||||||
const existingSet = new Set(queryParams.value.allEarNumbers || [])
|
|
||||||
const newEarNumbers = []
|
|
||||||
const duplicates = []
|
|
||||||
|
|
||||||
earNumbers.forEach(earNumber => {
|
|
||||||
if (!existingSet.has(earNumber)) {
|
|
||||||
newEarNumbers.push(earNumber)
|
|
||||||
existingSet.add(earNumber)
|
|
||||||
} else {
|
|
||||||
duplicates.push(earNumber)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 添加新耳号
|
|
||||||
if (newEarNumbers.length > 0) {
|
|
||||||
queryParams.value.allEarNumbers = [
|
|
||||||
...(queryParams.value.allEarNumbers || []),
|
|
||||||
...newEarNumbers
|
|
||||||
]
|
|
||||||
|
|
||||||
const message = `成功添加 ${newEarNumbers.length} 个耳号,当前共 ${queryParams.value.allEarNumbers.length} 个` +
|
|
||||||
(duplicates.length > 0 ? `,已忽略 ${duplicates.length} 个重复耳号` : '')
|
|
||||||
|
|
||||||
proxy.$modal.msgSuccess(message)
|
|
||||||
} else if (duplicates.length > 0) {
|
|
||||||
proxy.$modal.msgWarning(`所有耳号均已存在,当前共 ${queryParams.value.allEarNumbers.length} 个`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空输入框
|
|
||||||
pasteInput.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 远程搜索耳号 */
|
/** 远程搜索耳号 */
|
||||||
function searchEarNumber(query) {
|
function searchEarNumber(query) {
|
||||||
@@ -560,41 +588,13 @@ function searchEarNumber(query) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 耳号选择变化处理 */
|
|
||||||
function handleEarNumberChange(value) {
|
|
||||||
queryParams.value.allEarNumbers = [...new Set(value)]
|
|
||||||
console.log(`已选择 ${queryParams.value.allEarNumbers.length} 个耳号:`, queryParams.value.allEarNumbers)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 切换展开/收起状态 */
|
/** 切换展开/收起状态 */
|
||||||
function toggleExpand() {
|
function toggleExpand() {
|
||||||
isExpanded.value = !isExpanded.value
|
isExpanded.value = !isExpanded.value
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 移除单个耳号 */
|
|
||||||
function handleRemoveEarNumber(tag) {
|
|
||||||
const index = queryParams.value.allEarNumbers.indexOf(tag)
|
|
||||||
if (index > -1) {
|
|
||||||
queryParams.value.allEarNumbers.splice(index, 1)
|
|
||||||
proxy.$modal.msgSuccess('已移除该耳号')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果删除后剩余<=2个,自动收起
|
|
||||||
if (queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
|
||||||
isExpanded.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 清空所有耳号 */
|
|
||||||
function clearAllEarNumbers() {
|
|
||||||
proxy.$modal.confirm('确定要清空所有已选择的耳号吗?').then(() => {
|
|
||||||
queryParams.value.allEarNumbers = []
|
|
||||||
pasteInput.value = ''
|
|
||||||
earNumberOptions.value = []
|
|
||||||
isExpanded.value = false // 重置展开状态
|
|
||||||
proxy.$modal.msgSuccess('已清空所有耳号')
|
|
||||||
}).catch(() => {})
|
|
||||||
}
|
|
||||||
/** 查询羊只死淘记录列表 */
|
/** 查询羊只死淘记录列表 */
|
||||||
function getList() {
|
function getList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -711,6 +711,9 @@ function resetQuery() {
|
|||||||
queryParams.value.handlerList = []
|
queryParams.value.handlerList = []
|
||||||
queryParams.value.workGroupList = []
|
queryParams.value.workGroupList = []
|
||||||
queryParams.value.deathDateRange = []
|
queryParams.value.deathDateRange = []
|
||||||
|
queryParams.value.allEarNumbers = [] // ✅ 添加这一行
|
||||||
|
earNumberOptions.value = [] // ✅ 添加这一行
|
||||||
|
isExpanded.value = false // ✅ 添加这一行
|
||||||
|
|
||||||
proxy.resetForm("queryRef")
|
proxy.resetForm("queryRef")
|
||||||
handleQuery()
|
handleQuery()
|
||||||
@@ -792,6 +795,93 @@ function handleExport() {
|
|||||||
proxy.download('sheep_death/death/export', params, `death_${new Date().getTime()}.xlsx`)
|
proxy.download('sheep_death/death/export', params, `death_${new Date().getTime()}.xlsx`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 处理粘贴内容提交 */
|
||||||
|
function handlePasteSubmit() {
|
||||||
|
if (!pasteInput.value || pasteInput.value.trim() === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持多种分隔符: 空格、换行、逗号、制表符
|
||||||
|
const separators = /[\s,,\n\r\t]+/
|
||||||
|
const earNumbers = pasteInput.value
|
||||||
|
.trim()
|
||||||
|
.split(separators)
|
||||||
|
.filter(item => item.trim() !== '')
|
||||||
|
.map(item => item.trim())
|
||||||
|
|
||||||
|
if (earNumbers.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去重并添加到已选列表
|
||||||
|
const existingSet = new Set(queryParams.value.allEarNumbers || [])
|
||||||
|
const newEarNumbers = []
|
||||||
|
const duplicates = []
|
||||||
|
|
||||||
|
earNumbers.forEach(earNumber => {
|
||||||
|
if (!existingSet.has(earNumber)) {
|
||||||
|
newEarNumbers.push(earNumber)
|
||||||
|
existingSet.add(earNumber)
|
||||||
|
} else {
|
||||||
|
duplicates.push(earNumber)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加新耳号
|
||||||
|
if (newEarNumbers.length > 0) {
|
||||||
|
queryParams.value.allEarNumbers = [
|
||||||
|
...(queryParams.value.allEarNumbers || []),
|
||||||
|
...newEarNumbers
|
||||||
|
]
|
||||||
|
|
||||||
|
const message = `成功添加 ${newEarNumbers.length} 个耳号,当前共 ${queryParams.value.allEarNumbers.length} 个` +
|
||||||
|
(duplicates.length > 0 ? `,已忽略 ${duplicates.length} 个重复耳号` : '')
|
||||||
|
|
||||||
|
proxy.$modal.msgSuccess(message)
|
||||||
|
} else if (duplicates.length > 0) {
|
||||||
|
proxy.$modal.msgWarning(`所有耳号均已存在,当前共 ${queryParams.value.allEarNumbers.length} 个`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空输入框
|
||||||
|
pasteInput.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 耳号选择变化处理 */
|
||||||
|
function handleEarNumberChange(value) {
|
||||||
|
queryParams.value.allEarNumbers = [...new Set(value)]
|
||||||
|
console.log(`已选择 ${queryParams.value.allEarNumbers.length} 个耳号:`, queryParams.value.allEarNumbers)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 移除单个耳号 */
|
||||||
|
function handleRemoveEarNumber(tag) {
|
||||||
|
const index = queryParams.value.allEarNumbers.indexOf(tag)
|
||||||
|
if (index > -1) {
|
||||||
|
queryParams.value.allEarNumbers.splice(index, 1)
|
||||||
|
proxy.$modal.msgSuccess('已移除该耳号')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果删除后剩余<=2个,自动收起
|
||||||
|
if (queryParams.value.allEarNumbers.length <= defaultShowCount) {
|
||||||
|
isExpanded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清空所有耳号 */
|
||||||
|
function clearAllEarNumbers() {
|
||||||
|
proxy.$modal.confirm('确定要清空所有已选择的耳号吗?').then(() => {
|
||||||
|
queryParams.value.allEarNumbers = []
|
||||||
|
pasteInput.value = ''
|
||||||
|
earNumberOptions.value = []
|
||||||
|
isExpanded.value = false // 重置展开状态
|
||||||
|
proxy.$modal.msgSuccess('已清空所有耳号')
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
getDiseaseTreeData()
|
getDiseaseTreeData()
|
||||||
getList()
|
getList()
|
||||||
|
|||||||
Reference in New Issue
Block a user