feat: 优化库位选择器,支持打开时自动回显至已选层级
This commit is contained in:
@ -64,6 +64,7 @@
|
|||||||
v-for="item in currentList"
|
v-for="item in currentList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="location-item"
|
class="location-item"
|
||||||
|
:class="{ 'is-selected': item.full_path === modelValue }"
|
||||||
>
|
>
|
||||||
<!-- 左侧热区:点击进入下级或选中 -->
|
<!-- 左侧热区:点击进入下级或选中 -->
|
||||||
<div
|
<div
|
||||||
@ -101,7 +102,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { ArrowDown, ArrowLeft, ArrowRight, Location } from '@element-plus/icons-vue'
|
import { ArrowDown, ArrowLeft, ArrowRight, Location } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
@ -145,6 +146,55 @@ const currentList = computed(() => {
|
|||||||
return lastNode?.children || []
|
return lastNode?.children || []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听弹窗显示状态,恢复选中层级
|
||||||
|
watch(popoverVisible, (visible) => {
|
||||||
|
if (visible) {
|
||||||
|
restoreSelection()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 根据 modelValue 恢复选择状态
|
||||||
|
const restoreSelection = () => {
|
||||||
|
if (!props.modelValue) {
|
||||||
|
// 无选中值,重置到顶层
|
||||||
|
currentPath.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据 full_path 查找父级路径
|
||||||
|
const path = findPathByFullPath(props.options, props.modelValue)
|
||||||
|
if (path) {
|
||||||
|
// 找到路径:还原 currentPath(不包含最后一个节点,因为它是当前选中的节点)
|
||||||
|
currentPath.value = path
|
||||||
|
} else {
|
||||||
|
// 未找到(可能树结构已变化),重置到顶层
|
||||||
|
currentPath.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据 full_path 在树中查找从根到目标节点的路径
|
||||||
|
const findPathByFullPath = (
|
||||||
|
tree: WarehouseItem[],
|
||||||
|
targetFullPath: string,
|
||||||
|
currentPath: WarehouseItem[] = []
|
||||||
|
): WarehouseItem[] | null => {
|
||||||
|
for (const node of tree) {
|
||||||
|
// 检查当前节点是否匹配
|
||||||
|
if (node.full_path === targetFullPath) {
|
||||||
|
return currentPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归检查子节点
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
const result = findPathByFullPath(node.children, targetFullPath, [...currentPath, node])
|
||||||
|
if (result) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// 处理弹窗显示/隐藏
|
// 处理弹窗显示/隐藏
|
||||||
const handleVisibleChange = (visible: boolean) => {
|
const handleVisibleChange = (visible: boolean) => {
|
||||||
popoverVisible.value = visible
|
popoverVisible.value = visible
|
||||||
@ -286,6 +336,16 @@ const handleSelect = (item: WarehouseItem) => {
|
|||||||
background: #f5f7fa;
|
background: #f5f7fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 选中高亮样式 */
|
||||||
|
.location-item.is-selected {
|
||||||
|
background: rgba(64, 158, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.location-item.is-selected .item-name {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
/* 左侧主热区 - 占80%宽度 */
|
/* 左侧主热区 - 占80%宽度 */
|
||||||
.item-main {
|
.item-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user