fix: BOM搜索子件名称+自动搜索防抖
This commit is contained in:
@ -140,24 +140,35 @@ class BomService:
|
||||
)
|
||||
)
|
||||
|
||||
# ★ 调试:打印 SQL 语句
|
||||
logger.info(f"[BOM List] keyword={keyword!r} → SQL:\n{str(query_base.statement.compile(compile_kwargs={'literal_binds': True}))}")
|
||||
|
||||
# 获取符合条件的唯一组合
|
||||
target_pairs = query_base.distinct().all()
|
||||
|
||||
if not target_pairs:
|
||||
return []
|
||||
|
||||
# 2. 聚合查询详情
|
||||
# 2. 聚合查询详情(★ 修复:使用 string_agg 聚合子件名称,解决步骤3过滤遗漏问题)
|
||||
results = []
|
||||
for bom_no, version in target_pairs:
|
||||
# ★ 使用子件的别名查询子件信息,聚合所有子件的名称和规格
|
||||
child_alias = db.aliased(MaterialBase)
|
||||
summary = db.session.query(
|
||||
BomTable.parent_id,
|
||||
MaterialBase.name.label('parent_name'),
|
||||
MaterialBase.spec_model.label('parent_spec'),
|
||||
MaterialBase.category.label('parent_category'),
|
||||
BomTable.is_enabled,
|
||||
func.count(BomTable.child_id).label('child_count')
|
||||
func.count(BomTable.child_id).label('child_count'),
|
||||
# ★ 聚合子件名称为逗号分隔字符串(用于步骤3关键词过滤)
|
||||
func.string_agg(child_alias.name, ', ').label('child_names'),
|
||||
# ★ 同时聚合子件规格(备用)
|
||||
func.string_agg(child_alias.spec_model, ', ').label('child_specs')
|
||||
).join(
|
||||
MaterialBase, BomTable.parent_id == MaterialBase.id
|
||||
).outerjoin(
|
||||
child_alias, BomTable.child_id == child_alias.id
|
||||
).filter(
|
||||
BomTable.bom_no == bom_no,
|
||||
BomTable.version == version
|
||||
@ -174,7 +185,9 @@ class BomService:
|
||||
'parent_spec': summary.parent_spec or '',
|
||||
'parent_category': summary.parent_category or '',
|
||||
'is_enabled': summary.is_enabled,
|
||||
'child_count': summary.child_count
|
||||
'child_count': summary.child_count,
|
||||
'child_names': summary.child_names or '', # ★ 新增:子件名称聚合
|
||||
'child_specs': summary.child_specs or '' # ★ 新增:子件规格聚合
|
||||
})
|
||||
|
||||
results.sort(key=lambda x: (x['bom_no'], x['version']), reverse=True)
|
||||
@ -188,6 +201,8 @@ class BomService:
|
||||
or kw in (r.get('parent_spec') or '').lower()
|
||||
or kw in (r.get('bom_no') or '').lower()
|
||||
or kw in (r.get('parent_category') or '').lower()
|
||||
or kw in (r.get('child_names') or '').lower() # ★ 修复:加入子件名称过滤
|
||||
or kw in (r.get('child_specs') or '').lower() # ★ 同步加入子件规格过滤
|
||||
]
|
||||
|
||||
# 按 parent_category 分组
|
||||
|
||||
@ -240,7 +240,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
|
||||
import { ref, reactive, onMounted, computed, nextTick, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus'
|
||||
import { Plus, Search, EditPen } from '@element-plus/icons-vue'
|
||||
@ -289,6 +289,15 @@ const activeCategories = ref([]) // 默认全部展开
|
||||
const searchKeyword = ref('')
|
||||
const childSearchKeyword = ref('')
|
||||
|
||||
// ★ 自动搜索:输入后 500ms 防抖触发搜索(无需回车)
|
||||
watch(searchKeyword, (val) => {
|
||||
// 防抖:延迟 500ms 执行,避免频繁请求
|
||||
clearTimeout((window as any)._bomSearchTimer)
|
||||
;(window as any)._bomSearchTimer = setTimeout(() => {
|
||||
fetchBomList()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
// ============================================================
|
||||
// 【改造】分页 + 远程搜索相关状态
|
||||
// ============================================================
|
||||
|
||||
Reference in New Issue
Block a user