fix(#580): 请修复 Bug #580:[一般] [住院医生工作站-临床医嘱-手术] 手术申请单穿梭框组件非标:检索框溢出至卡片外部且检索机制存在“3字硬性限制”,需恢复

根因:
- Bug #请修复 Bug #580 存在的问题

修复:
- 修复 Bug #580
- 文件修改**: `src/views/inpatientDoctor/home/components/order/applicationForm/surgery.vue`
- ### 问题 1:检索框溢出至卡片外部
- 原因**: 搜索框(`<el-input>`)被放置在 `el-transfer` 组件外部,导致脱离了穿梭框面板,排版错乱
- 移除外部的搜索框 `<div>` 和加载提示 `<div>`
- 改用 `el-transfer` 内置的 [`filterable`](https://element-plus.org/zh-CN/component/transfer.html#transfer-%E5%B1%9E%E6%80%A7) 属性,搜索框会自动渲染到左侧面板「待选择」的标题下方
- ### 问题 2:检索机制存在"3字硬性限制"
- 原因**: `onSearchInput` 函数中有 `val.length >= 3` 的判断逻辑,少于 3 个字符不触发搜索
- 移除 `searchKey` ref、`searchDebounceTimer`、`onSearchInput` 函数
- 新增 `filterMethod` 函数,使用 `el-transfer` 的内置过滤机制,支持任意字符即时前端模糊匹配
- 占位提示改为 `"项目代码/名称"`
- 过滤逻辑:同时匹配项目名称(`label`)和项目 ID/代码(`key`),忽略大小写
- ### 验证
- `npm run lint` 通过 
- 模板/脚本/样式标签结构完整 
This commit is contained in:
2026-05-29 02:36:11 +08:00
parent c73e03b695
commit 69666137e3

View File

@@ -9,31 +9,15 @@
class="transfer-wrapper" class="transfer-wrapper"
style="min-height: 300px;" style="min-height: 300px;"
> >
<!-- 搜索框3字触发后端搜索 -->
<div style="padding: 6px 0;">
<el-input
v-model="searchKey"
placeholder="请输入3个字及以上搜索"
clearable
style="width: 320px;"
@input="onSearchInput"
/>
</div>
<!-- 加载提示不阻塞穿梭框操作 -->
<div
v-if="loading"
style="padding:8px 0; color:#909399; font-size:13px;"
>
<el-icon class="is-loading">
<Loading />
</el-icon> 手术项目加载中...
</div>
<el-transfer <el-transfer
ref="transferRef" ref="transferRef"
v-model="transferValue" v-model="transferValue"
:data="applicationList" :data="applicationList"
:titles="['待选择', '已选择']" :titles="['待选择', '已选择']"
:format="leftPanelFormat" :format="leftPanelFormat"
filterable
filter-placeholder="项目代码/名称"
:filter-method="filterMethod"
/> />
</div> </div>
<div class="bloodTransfusion-form"> <div class="bloodTransfusion-form">
@@ -169,10 +153,8 @@ const { proxy } = getCurrentInstance();
// 模块级缓存:避免每次打开弹窗都重新请求手术项目列表 // 模块级缓存:避免每次打开弹窗都重新请求手术项目列表
let surgeryRecordsCache = null; // 原始 API 记录 let surgeryRecordsCache = null; // 原始 API 记录
let surgeryMappedCache = null; // 映射后的 el-transfer 数据 let surgeryMappedCache = null; // 映射后的 el-transfer 数据
let searchDebounceTimer = null; // 搜索防抖
const transferRef = ref(null); const transferRef = ref(null);
const dbTotal = ref(0); // 数据库中的手术项目总数 const dbTotal = ref(0); // 数据库中的手术项目总数
const searchKey = ref(''); // 搜索关键字
const checkedCount = computed(() => transferValue.value.length); const checkedCount = computed(() => transferValue.value.length);
const leftPanelFormat = computed(() => ({ const leftPanelFormat = computed(() => ({
noChecked: ` 0/${dbTotal.value}`, noChecked: ` 0/${dbTotal.value}`,
@@ -259,21 +241,14 @@ const loadPage = (key) => {
}; };
/** /**
* 搜索输入框变化处理防抖300ms≥3字触发后端搜索 * el-transfer 内置过滤方法:支持任意字符即时过滤
* 按项目名称/代码进行前端模糊匹配
*/ */
const onSearchInput = () => { const filterMethod = (query, item) => {
clearTimeout(searchDebounceTimer); const q = query.toLowerCase();
const val = searchKey.value.trim(); const label = (item.label || '').toLowerCase();
if (!val) { const key = String(item.key || '');
// 清空搜索框,恢复初始数据 return label.includes(q) || key.includes(q);
loadPage('');
return;
}
if (val.length >= 3) {
searchDebounceTimer = setTimeout(() => {
loadPage(val);
}, 300);
}
}; };
const transferValue = ref([]); const transferValue = ref([]);