2025-10-28 19:01:57 +08:00
|
|
|
|
<template>
|
2025-11-25 01:13:26 +08:00
|
|
|
|
<div
|
|
|
|
|
|
:class="['actual-warehouse-select', { 'is-block': block }]"
|
|
|
|
|
|
:style="wrapperStyle"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-cascader
|
|
|
|
|
|
ref="cascader"
|
|
|
|
|
|
v-model="innerPath"
|
|
|
|
|
|
:props="cascaderProps"
|
|
|
|
|
|
:placeholder="placeholder"
|
|
|
|
|
|
:clearable="clearable"
|
|
|
|
|
|
:show-all-levels="true"
|
|
|
|
|
|
:emit-path="true"
|
|
|
|
|
|
style="width: 100%;"
|
|
|
|
|
|
@change="handleChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2025-10-28 19:01:57 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-11-25 01:13:26 +08:00
|
|
|
|
import { listActualWarehouse } from '@/api/wms/actualWarehouse';
|
2025-10-28 19:01:57 +08:00
|
|
|
|
|
|
|
|
|
|
export default {
|
2025-11-25 01:13:26 +08:00
|
|
|
|
name: 'ActualWarehouseSelect',
|
|
|
|
|
|
props: {
|
|
|
|
|
|
// 对外仍然是「单个 ID」,即第三级 actualWarehouseId
|
|
|
|
|
|
value: {
|
|
|
|
|
|
type: [Number, String, null],
|
|
|
|
|
|
default: null
|
|
|
|
|
|
},
|
|
|
|
|
|
placeholder: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: '请选择实际库位'
|
|
|
|
|
|
},
|
|
|
|
|
|
clearable: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true
|
|
|
|
|
|
},
|
|
|
|
|
|
// 已经不再显示“最高级”
|
|
|
|
|
|
showTop: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: false
|
|
|
|
|
|
},
|
|
|
|
|
|
block: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: false
|
|
|
|
|
|
},
|
|
|
|
|
|
width: {
|
|
|
|
|
|
type: [String, Number],
|
|
|
|
|
|
default: 240
|
|
|
|
|
|
},
|
|
|
|
|
|
size: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: 'small'
|
|
|
|
|
|
}
|
2025-10-28 19:01:57 +08:00
|
|
|
|
},
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
2025-11-25 01:13:26 +08:00
|
|
|
|
// 级联组件内部使用的「路径值」,例如 [一级ID, 二级ID, 三级ID]
|
|
|
|
|
|
innerPath: [],
|
|
|
|
|
|
// 记录所有已加载节点(如果后面要根据 ID 反查路径,可复用)
|
|
|
|
|
|
allLoadedNodes: []
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
wrapperStyle() {
|
|
|
|
|
|
const widthValue = this.block
|
|
|
|
|
|
? '100%'
|
|
|
|
|
|
: (typeof this.width === 'number' ? `${this.width}px` : this.width);
|
|
|
|
|
|
return { width: widthValue };
|
|
|
|
|
|
},
|
|
|
|
|
|
// el-cascader 的 props 配置
|
|
|
|
|
|
cascaderProps() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
lazy: true,
|
|
|
|
|
|
lazyLoad: this.loadNode, // 懒加载方法
|
|
|
|
|
|
checkStrictly: false, // 只允许选叶子节点
|
|
|
|
|
|
value: 'value',
|
|
|
|
|
|
label: 'label',
|
|
|
|
|
|
children: 'children'
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
watch: {
|
|
|
|
|
|
// 外部把 value 置空时,同步清空面板
|
|
|
|
|
|
value(val) {
|
|
|
|
|
|
if (val == null || val === '') {
|
|
|
|
|
|
this.innerPath = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 级联懒加载
|
|
|
|
|
|
* node.level:
|
|
|
|
|
|
* 0:根(还没选任何东西,parentId = 0 -> 加载一级)
|
|
|
|
|
|
* 1:一级节点,加载二级
|
|
|
|
|
|
* 2:二级节点,加载三级(三级设为叶子,不再展开)
|
|
|
|
|
|
*/
|
|
|
|
|
|
loadNode(node, resolve) {
|
|
|
|
|
|
const { level, value } = node;
|
|
|
|
|
|
|
|
|
|
|
|
// 超过第三级就不再加载
|
|
|
|
|
|
if (level >= 3) {
|
|
|
|
|
|
resolve([]);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const parentId = level === 0 ? 0 : value;
|
|
|
|
|
|
|
|
|
|
|
|
listActualWarehouse({ parentId }).then(res => {
|
|
|
|
|
|
const list = (res.data || []).map(item => {
|
|
|
|
|
|
const nextLevel = level + 1;
|
|
|
|
|
|
const isLeafLevel = nextLevel >= 3; // 第三级为叶子,不能再展开
|
|
|
|
|
|
|
|
|
|
|
|
const nodeData = {
|
|
|
|
|
|
value: item.actualWarehouseId,
|
|
|
|
|
|
label: item.actualWarehouseName,
|
|
|
|
|
|
leaf: isLeafLevel,
|
|
|
|
|
|
// 只有第三级可选;一、二级全部 disabled
|
|
|
|
|
|
disabled: nextLevel < 3 || item.isEnabled === false,
|
|
|
|
|
|
// 保留原始数据和层级
|
|
|
|
|
|
raw: item,
|
|
|
|
|
|
level: nextLevel
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.registerNode(nodeData);
|
|
|
|
|
|
return nodeData;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
resolve(list);
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
console.error('加载仓库树失败:', err);
|
|
|
|
|
|
resolve([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 把节点放进缓存数组里,后面如需扩展可用 */
|
|
|
|
|
|
registerNode(node) {
|
|
|
|
|
|
const id = node.value;
|
|
|
|
|
|
const idx = this.allLoadedNodes.findIndex(
|
|
|
|
|
|
n => String(n.value) === String(id)
|
|
|
|
|
|
);
|
|
|
|
|
|
if (idx === -1) {
|
|
|
|
|
|
this.allLoadedNodes.push(node);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.$set(this.allLoadedNodes, idx, {
|
|
|
|
|
|
...this.allLoadedNodes[idx],
|
|
|
|
|
|
...node
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 选中变化:
|
|
|
|
|
|
* value 是路径数组,如 [一级ID, 二级ID, 三级ID]
|
|
|
|
|
|
* 我们对外只抛最后一个(第三级)ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
handleChange(value) {
|
|
|
|
|
|
if (!Array.isArray(value) || value.length === 0) {
|
|
|
|
|
|
this.$emit('input', null);
|
|
|
|
|
|
this.$emit('select', null);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const leafId = value[value.length - 1];
|
|
|
|
|
|
|
|
|
|
|
|
// 拿到当前选中节点,获取完整路径信息
|
|
|
|
|
|
const nodes = this.$refs.cascader.getCheckedNodes();
|
|
|
|
|
|
let payload = null;
|
|
|
|
|
|
if (nodes && nodes.length > 0) {
|
|
|
|
|
|
const node = nodes[0];
|
|
|
|
|
|
const pathNodes = node.path || [];
|
|
|
|
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
id: leafId,
|
|
|
|
|
|
pathIds: pathNodes.map(n => n.value),
|
|
|
|
|
|
pathLabels: pathNodes.map(n => n.label),
|
|
|
|
|
|
// 原始 data(如果需要后台做别的处理可以用)
|
|
|
|
|
|
rawPath: pathNodes.map(n => n.data || n.raw || {})
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.$emit('input', leafId);
|
|
|
|
|
|
this.$emit('select', payload);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 外部刷新:如果以后需要强制重载,可以扩展这里(目前不需要缓存) */
|
|
|
|
|
|
refresh() {
|
|
|
|
|
|
this.innerPath = [];
|
|
|
|
|
|
this.allLoadedNodes = [];
|
|
|
|
|
|
// el-cascader 的懒加载不需要预载,这里清空即可
|
2025-10-28 19:01:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-25 01:13:26 +08:00
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.actual-warehouse-select {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.actual-warehouse-select.is-block {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 让级联宽度占满容器,其他高度、边框等跟 el-select 共用全局 .el-input__inner 样式 */
|
|
|
|
|
|
.actual-warehouse-select .el-cascader {
|
|
|
|
|
|
width: 100%;
|
2025-10-29 14:33:26 +08:00
|
|
|
|
}
|
2025-11-25 01:13:26 +08:00
|
|
|
|
</style>
|