✨ feat(mes): 新增物料产品选择器 V2 组件
parent
9f9ac51edf
commit
1f9380ba90
|
|
@ -1,78 +0,0 @@
|
|||
<template>
|
||||
<div class="head-container">
|
||||
<el-input v-model="filterName" class="mb-20px" clearable placeholder="请输入分类名称">
|
||||
<template #prefix>
|
||||
<Icon icon="ep:search" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="itemTypeList"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:props="defaultProps"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ElTree } from 'element-plus'
|
||||
import { MdItemTypeApi } from '@/api/mes/md/item/type'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
|
||||
defineOptions({ name: 'MesItemTypeTree' })
|
||||
|
||||
const filterName = ref('')
|
||||
const itemTypeList = ref<Tree[]>([])
|
||||
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||
|
||||
/** 获得分类树 */
|
||||
const getTree = async () => {
|
||||
const res = await MdItemTypeApi.getItemTypeSimpleList()
|
||||
itemTypeList.value = []
|
||||
itemTypeList.value.push(...handleTree(res))
|
||||
}
|
||||
|
||||
/** 基于名字过滤 */
|
||||
const filterNode = (name: string, data: Tree) => {
|
||||
if (!name) {
|
||||
return true
|
||||
}
|
||||
return data.name.includes(name)
|
||||
}
|
||||
|
||||
/** 处理分类被点击 */
|
||||
let currentNode: any = {}
|
||||
const handleNodeClick = async (row: { [key: string]: any }, treeNode: any) => {
|
||||
if (currentNode && currentNode.name === row.name) {
|
||||
treeNode.checked = !treeNode.checked
|
||||
} else {
|
||||
treeNode.checked = true
|
||||
}
|
||||
if (treeNode.checked) {
|
||||
currentNode = row
|
||||
emits('node-click', row)
|
||||
} else {
|
||||
treeRef.value!.setCurrentKey(undefined)
|
||||
emits('node-click', undefined)
|
||||
currentNode = null
|
||||
}
|
||||
}
|
||||
const emits = defineEmits(['node-click'])
|
||||
|
||||
/** 监听过滤名称 */
|
||||
watch(filterName, (val) => {
|
||||
treeRef.value!.filter(val)
|
||||
})
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
await getTree()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<!--
|
||||
MES 物料分类树面板
|
||||
|
||||
功能:加载物料分类树 + 关键字过滤 + 点击节点通知父组件
|
||||
用法:<MdItemTypeTree @node-click="handleTypeClick" />
|
||||
说明:
|
||||
- 组件 mount 后自动加载数据,也可通过 ref 调用 loadTree() 手动刷新
|
||||
- 支持 toggle:点击已选中节点会取消选中(emit undefined)
|
||||
Events:
|
||||
nodeClick(data: MdItemTypeVO | undefined) — 点击树节点时触发;取消选中时为 undefined
|
||||
Expose:
|
||||
loadTree() — 手动刷新分类树
|
||||
clearCurrent() — 清除当前选中节点高亮
|
||||
-->
|
||||
<template>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="搜索分类"
|
||||
clearable
|
||||
class="mb-12px"
|
||||
:prefix-icon="iconSearch"
|
||||
/>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="treeData"
|
||||
:props="treeProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
node-key="id"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
||||
import { handleTree } from '@/utils/tree'
|
||||
import { Search as iconSearch } from '@element-plus/icons-vue'
|
||||
|
||||
defineOptions({ name: 'MdItemTypeTree' })
|
||||
|
||||
const emit = defineEmits<{
|
||||
nodeClick: [data: MdItemTypeVO | undefined]
|
||||
}>()
|
||||
|
||||
const treeRef = ref() // 树组件 Ref
|
||||
const filterText = ref('') // 搜索关键字
|
||||
const treeData = ref<MdItemTypeVO[]>([]) // 树形数据
|
||||
const treeProps = { children: 'children', label: 'name' } // 树属性映射
|
||||
let currentNodeId: number | undefined // 当前选中节点 ID(用于 toggle 判断)
|
||||
|
||||
/** 过滤树节点(按名称匹配) */
|
||||
const filterNode = (value: string, data: MdItemTypeVO) => {
|
||||
if (!value) {
|
||||
return true
|
||||
}
|
||||
return data.name?.includes(value)
|
||||
}
|
||||
|
||||
/** 监听搜索关键字变化,触发树过滤 */
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value?.filter(val)
|
||||
})
|
||||
|
||||
/** 点击树节点:支持 toggle(再次点击同一节点取消选中) */
|
||||
const handleNodeClick = (data: MdItemTypeVO) => {
|
||||
if (currentNodeId === data.id) {
|
||||
// 再次点击同一节点:取消选中
|
||||
treeRef.value?.setCurrentKey(undefined)
|
||||
currentNodeId = undefined
|
||||
emit('nodeClick', undefined)
|
||||
} else {
|
||||
// 选中新节点
|
||||
currentNodeId = data.id
|
||||
emit('nodeClick', data)
|
||||
}
|
||||
}
|
||||
|
||||
/** 加载分类树数据 */
|
||||
const loadTree = async () => {
|
||||
const list = await MdItemTypeApi.getItemTypeSimpleList()
|
||||
treeData.value = handleTree(list)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadTree()
|
||||
})
|
||||
|
||||
/** 清除当前选中节点高亮 */
|
||||
const clearCurrent = () => {
|
||||
treeRef.value?.setCurrentKey(undefined)
|
||||
currentNodeId = undefined
|
||||
}
|
||||
|
||||
defineExpose({ loadTree, clearCurrent })
|
||||
</script>
|
||||
Loading…
Reference in New Issue