Files
bj_power/bj_power_wms/frontend/src/components/MaterialSelect.vue
T
SunYF 132c3ed6bd docs(test): 更新电表箱装配业务回归测试文档
- 将文档从代码审计任务转换为端到端业务回归测试链路
- 重新组织文档结构为链路总览、示例数据基线和详细步骤
- 添加完整的业务场景清单涵盖WMS/MES/工位终端三大系统
- 定义统一的测试数据包括产品型号、物料清单、工位派工等
- 提供详细的步骤断言和数量等式验证方法
- 建立贯穿全链路的数据流向和状态变更追踪体系
2026-09-21 10:48:53 +08:00

91 lines
3.5 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
// 物料下拉选择器(公共组件,全项目统一 —— 客户诉求 问题18:下拉显示字段 编码/图号/类型/品类)
// 规范:数据量不确定的下拉只加载最近 100 条(created_at desc),支持远程模糊搜索(keyword 查询,结果仍封顶 100)。
// 选中后通过 item-change 事件抛出完整物料对象(无匹配为 null),供页面读取 manageMode/itemType 自动判定类型,
// 杜绝让客户手动选择「电气件/结构件」——物料类型物料档案里就有(问题18)。
import { ref, onMounted } from 'vue'
import request from '../utils/request'
const props = defineProps({
modelValue: { type: [String, Array], default: '' },
multiple: { type: Boolean, default: false },
manageMode: { type: Number, default: 0 }, // 0=全部 1=结构件 2=电气件
itemType: { type: Number, default: 0 }, // 0=全部 1原材料 2半成品 3成品 4其他
excludeItemType: { type: Number, default: 0 }, // 排除指定品类,如结构件/电气件入库排除「其他」(4)
placeholder: { type: String, default: '选择物料' },
clearable: { type: Boolean, default: true },
width: { type: String, default: '100%' }
})
const emit = defineEmits(['update:modelValue', 'item-change'])
const options = ref([])
const loading = ref(false)
// 类型标签(问题18 类型含「其他」):其他品类(itemType=4)统一显示「其他」,否则按管理粒度分结构件/电气件
function typeLabel(m) {
if (m?.itemType === 4) return '其他'
return m?.manageMode === 2 ? '电气件' : '结构件'
}
// 品类标签:1原材料/2半成品/3成品/4其他
function catLabel(m) {
switch (m?.itemType) {
case 1: return '原材料'
case 2: return '半成品'
case 3: return '成品'
case 4: return '其他'
default: return '-'
}
}
// 选中回显文本:编码 图号 类型 品类
function optionLabel(m) {
return `${m.code} ${m.name || ''} [${typeLabel(m)}·${catLabel(m)}]`
}
// 最近 100 条 + keyword 模糊搜索(后端 /material/query 兼容空 keyword
async function load(kw = '') {
loading.value = true
try {
const data = await request.get('/material/query', {
params: {
page: 1, pageSize: 100, keyword: kw || '',
manageMode: props.manageMode || '',
itemType: props.itemType || '',
excludeItemType: props.excludeItemType || ''
}
})
options.value = data?.list || []
} catch {
options.value = []
} finally {
loading.value = false
}
}
function onChange(v) {
emit('update:modelValue', v)
if (props.multiple) {
emit('item-change', options.value.filter((o) => v.includes(o.code)))
} else {
emit('item-change', options.value.find((o) => o.code === v) || null)
}
}
// 展开下拉即重拉最近 100 条(仅在未输入搜索词时):新建/修改物料后无需刷新页面即可选到最新数据。
function onVisible(v) { if (v) load('') }
onMounted(() => load(''))
</script>
<template>
<el-select :model-value="modelValue" :multiple="multiple" filterable remote clearable
:remote-method="load" :loading="loading" :placeholder="placeholder"
:style="{ width }" @change="onChange" @visible-change="onVisible">
<el-option v-for="m in options" :key="m.id" :value="m.code" :label="optionLabel(m)">
<span style="float:left">{{ m.code }} {{ m.name || '' }}</span>
<span style="float:right;color:#8492a6;font-size:12px;margin-left:16px">
{{ typeLabel(m) }}{{ catLabel(m) }}
</span>
</el-option>
</el-select>
</template>