前后端修改
This commit is contained in:
@@ -9,6 +9,15 @@ export function listActualWarehouse(query) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取完整三级目录
|
||||||
|
export function listActualWarehouseTree(query) {
|
||||||
|
return request({
|
||||||
|
url: '/wms/actualWarehouse/tree',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 查询实际库区/库位自关联详细
|
// 查询实际库区/库位自关联详细
|
||||||
export function getActualWarehouse(actualWarehouseId) {
|
export function getActualWarehouse(actualWarehouseId) {
|
||||||
return request({
|
return request({
|
||||||
@@ -26,6 +35,25 @@ export function addActualWarehouse(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导入实际库区/库位
|
||||||
|
export function importActualWarehouse(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wms/actualWarehouse/importData',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量新增三级目录
|
||||||
|
export function createActualWarehouseHierarchy(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wms/actualWarehouse/hierarchy',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 修改实际库区/库位自关联
|
// 修改实际库区/库位自关联
|
||||||
export function updateActualWarehouse(data) {
|
export function updateActualWarehouse(data) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@@ -793,6 +793,52 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Treeselect 样式
|
||||||
|
.vue-treeselect {
|
||||||
|
&__control {
|
||||||
|
min-height: 24px;
|
||||||
|
border-radius: 0;
|
||||||
|
border-color: $--border-color-light;
|
||||||
|
background: linear-gradient(180deg, #fdfdff 0%, #f4f6fa 100%);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__single-value,
|
||||||
|
&__placeholder,
|
||||||
|
&__input-container {
|
||||||
|
line-height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $--color-text-regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__control-arrow-container {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__menu {
|
||||||
|
background: $--metal-gradient-light;
|
||||||
|
border: 1px solid $--border-color-light;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: $--metal-shadow;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__option {
|
||||||
|
color: $--color-text-regular;
|
||||||
|
padding: 6px 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
&--highlight {
|
||||||
|
background-color: rgba($--color-primary, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
background-color: rgba($--color-primary, .20);
|
||||||
|
color: $--color-text-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 开关
|
// 开关
|
||||||
.el-switch {
|
.el-switch {
|
||||||
.el-switch__core {
|
.el-switch__core {
|
||||||
|
|||||||
@@ -1,156 +1,189 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 100%; max-width: 300px;">
|
<div :class="['actual-warehouse-select', { 'is-block': block }]" :style="wrapperStyle">
|
||||||
<treeselect
|
<el-select
|
||||||
:max-height="200"
|
|
||||||
v-model="innerValue"
|
v-model="innerValue"
|
||||||
:options="warehouseOptions"
|
|
||||||
:normalizer="normalizer"
|
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:clearable="clearable"
|
:clearable="clearable"
|
||||||
search-nested
|
filterable
|
||||||
:load-options="loadOptions"
|
:filter-method="handleFilter"
|
||||||
@input="onInput"
|
:disabled="disabled"
|
||||||
/>
|
size="small"
|
||||||
|
class="actual-warehouse-select__inner"
|
||||||
|
@change="handleChange"
|
||||||
|
@visible-change="handleVisibleChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="option in displayOptions"
|
||||||
|
:key="option.actualWarehouseId"
|
||||||
|
:label="option.fullLabel"
|
||||||
|
:value="option.actualWarehouseId"
|
||||||
|
>
|
||||||
|
<div class="option-content">
|
||||||
|
<span class="level-tag">{{ levelLabels[option.level] }}</span>
|
||||||
|
<span class="option-text">{{ option.fullLabel }}</span>
|
||||||
|
</div>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Treeselect from '@riophae/vue-treeselect';
|
import { listActualWarehouseTree } from '@/api/wms/actualWarehouse';
|
||||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
|
|
||||||
import { listActualWarehouse } from '@/api/wms/actualWarehouse';
|
const LEVEL_LABELS = {
|
||||||
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect';
|
1: '一级',
|
||||||
|
2: '二级',
|
||||||
|
3: '三级'
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ActualWarehouseSelect',
|
name: 'ActualWarehouseSelect',
|
||||||
components: { Treeselect },
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [Number, String, null], // 仅保留单选类型
|
type: [Number, String, null],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '请选择库区/仓库/库位'
|
default: '请选择实际库区/库位'
|
||||||
},
|
},
|
||||||
clearable: {
|
clearable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
showTop: {
|
block: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true // 是否显示顶级节点(actualWarehouseId=0)
|
default: false
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 240
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
innerValue: this.value,
|
innerValue: this.value,
|
||||||
warehouseOptions: [], // 初始选项(含未加载子节点的节点,标记 children: null)
|
flatOptions: [],
|
||||||
loadedChildren: {}, // 缓存已加载的子节点:key=父节点ID,value=子节点数组
|
displayOptions: [],
|
||||||
allLoadedNodes: [] // 存储所有已加载的节点,用于快速查找完整对象
|
levelLabels: LEVEL_LABELS
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
wrapperStyle() {
|
||||||
|
const widthValue = this.block ? '100%' : (typeof this.width === 'number' ? `${this.width}px` : this.width);
|
||||||
|
return { width: widthValue };
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(val) {
|
value(val) {
|
||||||
this.innerValue = val;
|
this.innerValue = val;
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
created() {
|
||||||
this.initOptions();
|
this.fetchTree();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 初始化顶级选项 */
|
async fetchTree() {
|
||||||
initOptions() {
|
try {
|
||||||
// 重置状态
|
const res = await listActualWarehouseTree();
|
||||||
this.loadedChildren = {};
|
this.flatOptions = this.flattenTree(res.data || []);
|
||||||
this.allLoadedNodes = [];
|
this.displayOptions = [...this.flatOptions];
|
||||||
this.warehouseOptions = [];
|
} catch (error) {
|
||||||
|
console.error('获取实际库区树失败', error);
|
||||||
if (this.showTop) {
|
|
||||||
// 显示顶级节点:标记 children: null 表示需要懒加载子节点
|
|
||||||
const topNode = {
|
|
||||||
actualWarehouseId: 0,
|
|
||||||
actualWarehouseName: '顶级节点',
|
|
||||||
children: null, // 关键:标记为未加载子节点
|
|
||||||
isDisabled: false
|
|
||||||
};
|
|
||||||
this.warehouseOptions.push(topNode);
|
|
||||||
this.allLoadedNodes.push(topNode);
|
|
||||||
} else {
|
|
||||||
// 不显示顶级节点:直接加载 parentId=0 的节点作为顶级(初始标记为未加载)
|
|
||||||
this.warehouseOptions.push({
|
|
||||||
actualWarehouseId: 'temp-parent-0', // 临时父节点ID(仅用于触发首次加载)
|
|
||||||
actualWarehouseName: '加载中...',
|
|
||||||
children: null,
|
|
||||||
isDisabled: true
|
|
||||||
});
|
|
||||||
// 触发首次加载 parentId=0 的节点
|
|
||||||
this.loadOptions({
|
|
||||||
action: LOAD_CHILDREN_OPTIONS,
|
|
||||||
parentNode: { id: 0 },
|
|
||||||
callback: (children) => {
|
|
||||||
this.warehouseOptions = children;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 懒加载核心方法 */
|
flattenTree(nodes, parentPath = [], level = 1) {
|
||||||
loadOptions({ action, parentNode, callback, instanceId }) {
|
const result = [];
|
||||||
// 仅处理 "加载子节点" 动作
|
nodes.forEach(node => {
|
||||||
if (action !== LOAD_CHILDREN_OPTIONS) {
|
const path = [...parentPath, node.actualWarehouseName];
|
||||||
callback();
|
const current = {
|
||||||
|
actualWarehouseId: node.actualWarehouseId,
|
||||||
|
parentId: node.parentId || 0,
|
||||||
|
level,
|
||||||
|
fullLabel: path.join(' / '),
|
||||||
|
descendantIds: [],
|
||||||
|
children: node.children || []
|
||||||
|
};
|
||||||
|
result.push(current);
|
||||||
|
if (node.children && node.children.length) {
|
||||||
|
const children = this.flattenTree(node.children, path, level + 1);
|
||||||
|
children.forEach(child => {
|
||||||
|
current.descendantIds.push(child.actualWarehouseId);
|
||||||
|
current.descendantIds.push(...child.descendantIds);
|
||||||
|
});
|
||||||
|
result.push(...children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFilter(keyword) {
|
||||||
|
const text = (keyword || '').trim();
|
||||||
|
if (!text) {
|
||||||
|
this.displayOptions = [...this.flatOptions];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('加载子节点请求参数:', parentNode);
|
const matchedIds = new Set();
|
||||||
|
this.flatOptions.forEach(option => {
|
||||||
const parentId = parentNode.actualWarehouseId; // 当前父节点ID(对应 actualWarehouseId)
|
if (option.fullLabel.includes(text)) {
|
||||||
|
matchedIds.add(option.actualWarehouseId);
|
||||||
// 2. 调用接口加载子节点(parentId 作为查询条件)
|
option.descendantIds.forEach(id => matchedIds.add(id));
|
||||||
listActualWarehouse({ parentId }).then(response => {
|
|
||||||
const children = response.data.map(item => ({
|
|
||||||
...item,
|
|
||||||
isDisabled: !item.isEnabled, // 禁用未启用的节点
|
|
||||||
children: item.hasChildren ?? true ? null : [] // 有子节点则标记 children: null(需懒加载),否则空数组
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 如果没有子节点了,则不添加children属性
|
|
||||||
if (children.length === 0) {
|
|
||||||
delete parentNode.children;
|
|
||||||
callback()
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 给父节点赋值子节点(treeselect 自动渲染)
|
|
||||||
parentNode.children = children;
|
|
||||||
|
|
||||||
// 6. 回调通知加载成功
|
|
||||||
callback();
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error('加载子节点失败:', error);
|
|
||||||
callback(new Error('加载失败,请重试'));
|
|
||||||
});
|
});
|
||||||
|
this.displayOptions = this.flatOptions.filter(option => matchedIds.has(option.actualWarehouseId));
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 节点格式标准化 */
|
handleVisibleChange(visible) {
|
||||||
normalizer(node) {
|
if (!visible) {
|
||||||
return {
|
this.displayOptions = [...this.flatOptions];
|
||||||
id: node.actualWarehouseId, // 节点唯一ID
|
}
|
||||||
label: node.actualWarehouseName, // 显示文本
|
|
||||||
children: node.children, // 子节点(null=未加载,[]=无节点)
|
|
||||||
isDisabled: node.isDisabled, // 是否禁用
|
|
||||||
raw: node // 保留原始节点数据,方便后续查找
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 选中值变化时触发(仅单选) */
|
handleChange(val) {
|
||||||
onInput(val) {
|
|
||||||
this.$emit('input', val);
|
this.$emit('input', val);
|
||||||
|
const node = this.flatOptions.find(option => option.actualWarehouseId === val);
|
||||||
|
this.$emit('select', node);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 外部刷新方法(如需重新加载数据可调用) */
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.initOptions();
|
this.fetchTree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.actual-warehouse-select {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actual-warehouse-select.is-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actual-warehouse-select__inner {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-tag {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
width: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-text {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -114,9 +114,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="扫码时间" align="center" prop="scanTime" width="155" :show-overflow-tooltip="true">
|
<el-table-column label="新增时间" align="center" prop="createTime" width="155" :show-overflow-tooltip="true">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.scanTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,11 @@
|
|||||||
|
|
||||||
<!-- 真实库区 -->
|
<!-- 真实库区 -->
|
||||||
<el-form-item label="真实库区">
|
<el-form-item label="真实库区">
|
||||||
<ActualWarehouseSelect v-model="queryParams.actualWarehouseId" @change="handleActualWarehouseChange" />
|
<ActualWarehouseSelect
|
||||||
|
v-model="queryParams.actualWarehouseId"
|
||||||
|
@change="handleActualWarehouseChange"
|
||||||
|
:width="220"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,212 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideType="hideType" />
|
<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>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BasePage from './panels/base.vue';
|
import { listActualWarehouse } from '@/api/wms/actualWarehouse';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
name: 'ActualWarehouseSelect',
|
||||||
BasePage
|
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'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
qrcode: true,
|
// 级联组件内部使用的「路径值」,例如 [一级ID, 二级ID, 三级ID]
|
||||||
querys: {
|
innerPath: [],
|
||||||
dataType: 1,
|
// 记录所有已加载节点(如果后面要根据 ID 反查路径,可复用)
|
||||||
// itemType: 'raw_material'
|
allLoadedNodes: []
|
||||||
materialType: '原料'
|
};
|
||||||
},
|
},
|
||||||
labelType: '2',
|
computed: {
|
||||||
hideType: true
|
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 的懒加载不需要预载,这里清空即可
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.actual-warehouse-select {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
.actual-warehouse-select.is-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 让级联宽度占满容器,其他高度、边框等跟 el-select 共用全局 .el-input__inner 样式 */
|
||||||
|
.actual-warehouse-select .el-cascader {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
<el-option :value="1" label="当前数据">当前数据</el-option>
|
<el-option :value="1" label="当前数据">当前数据</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="所在库位" prop="warehouseId" v-if="!hideWarehouseQuery">
|
<el-form-item label="逻辑库位" prop="warehouseId" v-if="!hideWarehouseQuery">
|
||||||
<warehouse-select v-model="queryParams.warehouseId" placeholder="请选择仓库/库区/库位"
|
<warehouse-select v-model="queryParams.warehouseId" placeholder="请选择仓库/库区/库位"
|
||||||
style="width: 100%; display: inline-block;" clearable />
|
style="width: 100%; display: inline-block;" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="实际库区" prop="actualWarehouseId" v-if="!hideWarehouseQuery">
|
<el-form-item label="实际库区" prop="actualWarehouseId" v-if="!hideWarehouseQuery">
|
||||||
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库位"
|
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库位"
|
||||||
style="width: 100%; display: inline-block;" clearable />
|
style="display: inline-block;" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="厂家卷号" prop="supplierCoilNo">
|
<el-form-item label="厂家卷号" prop="supplierCoilNo">
|
||||||
<el-input v-model="queryParams.supplierCoilNo" placeholder="请输入厂家原料卷号" clearable
|
<el-input v-model="queryParams.supplierCoilNo" placeholder="请输入厂家原料卷号" clearable
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="materialCoilList" @selection-change="handleSelectionChange" height="450px">
|
<el-table v-loading="loading" :data="materialCoilList" @selection-change="handleSelectionChange" >
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo" />
|
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo" />
|
||||||
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo" />
|
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo" />
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default {
|
|||||||
},
|
},
|
||||||
labelType: '3',
|
labelType: '3',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
hideType: true,
|
hideType: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,8 +171,12 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="真实库区" required>
|
<el-form-item label="真实库区" required>
|
||||||
<ActualWarehouseSelect v-model="item.actualWarehouseId" placeholder="请选择真实库区" style="width: 100%"
|
<ActualWarehouseSelect
|
||||||
filterable :disabled="readonly" />
|
v-model="item.actualWarehouseId"
|
||||||
|
placeholder="请选择真实库区"
|
||||||
|
block
|
||||||
|
:disabled="readonly"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -167,8 +167,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="真实库区" prop="warehouseId">
|
<el-form-item label="真实库区" prop="warehouseId">
|
||||||
<ActualWarehouseSelect v-model="updateForm.actualWarehouseId" placeholder="请选择真实库区" style="width: 100%"
|
<ActualWarehouseSelect
|
||||||
filterable :disabled="readonly" />
|
v-model="updateForm.actualWarehouseId"
|
||||||
|
placeholder="请选择真实库区"
|
||||||
|
block
|
||||||
|
:disabled="readonly"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,13 @@ package com.klp.controller;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import com.klp.common.annotation.RepeatSubmit;
|
import com.klp.common.annotation.RepeatSubmit;
|
||||||
@@ -16,9 +19,13 @@ import com.klp.common.core.domain.R;
|
|||||||
import com.klp.common.core.validate.AddGroup;
|
import com.klp.common.core.validate.AddGroup;
|
||||||
import com.klp.common.core.validate.EditGroup;
|
import com.klp.common.core.validate.EditGroup;
|
||||||
import com.klp.common.enums.BusinessType;
|
import com.klp.common.enums.BusinessType;
|
||||||
|
import com.klp.common.excel.ExcelResult;
|
||||||
import com.klp.common.utils.poi.ExcelUtil;
|
import com.klp.common.utils.poi.ExcelUtil;
|
||||||
import com.klp.domain.vo.WmsActualWarehouseVo;
|
import com.klp.domain.vo.WmsActualWarehouseVo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseImportVo;
|
||||||
import com.klp.domain.bo.WmsActualWarehouseBo;
|
import com.klp.domain.bo.WmsActualWarehouseBo;
|
||||||
|
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
|
||||||
import com.klp.service.IWmsActualWarehouseService;
|
import com.klp.service.IWmsActualWarehouseService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,6 +51,34 @@ public class WmsActualWarehouseController extends BaseController {
|
|||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取完整三级目录树
|
||||||
|
*/
|
||||||
|
@GetMapping("/tree")
|
||||||
|
public R<List<WmsActualWarehouseTreeVo>> tree(WmsActualWarehouseBo bo) {
|
||||||
|
return R.ok(iWmsActualWarehouseService.queryTree(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入实际库区/库位数据
|
||||||
|
*/
|
||||||
|
@Log(title = "实际库区/库位自关联", businessType = BusinessType.IMPORT)
|
||||||
|
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
||||||
|
ExcelResult<WmsActualWarehouseImportVo> result = ExcelUtil.importExcel(file.getInputStream(), WmsActualWarehouseImportVo.class, true);
|
||||||
|
iWmsActualWarehouseService.importHierarchy(result.getList());
|
||||||
|
return R.ok(result.getAnalysis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载导入模板
|
||||||
|
*/
|
||||||
|
@PostMapping("/importTemplate")
|
||||||
|
public void importTemplate(HttpServletResponse response) {
|
||||||
|
List<WmsActualWarehouseImportVo> template = buildTemplateData();
|
||||||
|
ExcelUtil.exportExcel(template, "实际库区导入模板", WmsActualWarehouseImportVo.class, response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出实际库区/库位自关联列表
|
* 导出实际库区/库位自关联列表
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +110,15 @@ public class WmsActualWarehouseController extends BaseController {
|
|||||||
return toAjax(iWmsActualWarehouseService.insertByBo(bo));
|
return toAjax(iWmsActualWarehouseService.insertByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增或复用层级目录
|
||||||
|
*/
|
||||||
|
@Log(title = "实际库区/库位自关联-批量新增", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/hierarchy")
|
||||||
|
public R<List<Long>> addHierarchy(@Validated @RequestBody WmsActualWarehouseHierarchyBo bo) {
|
||||||
|
return R.ok(iWmsActualWarehouseService.createHierarchy(bo));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改实际库区/库位自关联
|
* 修改实际库区/库位自关联
|
||||||
*/
|
*/
|
||||||
@@ -96,4 +140,30 @@ public class WmsActualWarehouseController extends BaseController {
|
|||||||
@PathVariable Long[] actualWarehouseIds) {
|
@PathVariable Long[] actualWarehouseIds) {
|
||||||
return toAjax(iWmsActualWarehouseService.deleteWithValidByIds(Arrays.asList(actualWarehouseIds), true));
|
return toAjax(iWmsActualWarehouseService.deleteWithValidByIds(Arrays.asList(actualWarehouseIds), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<WmsActualWarehouseImportVo> buildTemplateData() {
|
||||||
|
List<WmsActualWarehouseImportVo> list = new ArrayList<>();
|
||||||
|
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-A", "A通道", 10L, "L1-001-A-01", "A-01货位", 10L));
|
||||||
|
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-A", "A通道", 10L, "L1-001-A-02", "A-02货位", 20L));
|
||||||
|
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-B", "B通道", 20L, "L1-001-B-01", "B-01货位", 10L));
|
||||||
|
list.add(buildRow("L1-002", "二号库区", 20L, "L1-002-A", "冷藏区", 10L, null, null, null));
|
||||||
|
list.add(buildRow("L1-002", "二号库区", 20L, "L1-002-B", "常温区", 20L, "L1-002-B-01", "常温-01", 10L));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WmsActualWarehouseImportVo buildRow(String l1Code, String l1Name, Long l1Sort,
|
||||||
|
String l2Code, String l2Name, Long l2Sort,
|
||||||
|
String l3Code, String l3Name, Long l3Sort) {
|
||||||
|
WmsActualWarehouseImportVo vo = new WmsActualWarehouseImportVo();
|
||||||
|
vo.setLevelOneCode(l1Code);
|
||||||
|
vo.setLevelOneName(l1Name);
|
||||||
|
vo.setLevelOneSort(l1Sort);
|
||||||
|
vo.setLevelTwoCode(l2Code);
|
||||||
|
vo.setLevelTwoName(l2Name);
|
||||||
|
vo.setLevelTwoSort(l2Sort);
|
||||||
|
vo.setLevelThreeCode(l3Code);
|
||||||
|
vo.setLevelThreeName(l3Name);
|
||||||
|
vo.setLevelThreeSort(l3Sort);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.klp.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于批量新增/匹配一级-三级节点的请求体
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class WmsActualWarehouseHierarchyBo implements Serializable {
|
||||||
|
|
||||||
|
@NotEmpty(message = "三级目录数据不能为空")
|
||||||
|
@Valid
|
||||||
|
private List<HierarchyLevel> levels = new ArrayList<>();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class HierarchyLevel implements Serializable {
|
||||||
|
/**
|
||||||
|
* 层级:1/2/3
|
||||||
|
*/
|
||||||
|
@NotNull(message = "层级不能为空")
|
||||||
|
@Min(value = 1, message = "层级最小为1")
|
||||||
|
@Max(value = 3, message = "层级最大为3")
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选中了已有节点时携带的ID,用于比对去重
|
||||||
|
*/
|
||||||
|
private Long actualWarehouseId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码(当 actualWarehouseId 为空时必填)
|
||||||
|
*/
|
||||||
|
private String actualWarehouseCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称(当 actualWarehouseId 为空时必填)
|
||||||
|
*/
|
||||||
|
private String actualWarehouseName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同级排序号
|
||||||
|
*/
|
||||||
|
private Long sortNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private Integer isEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.klp.domain.vo;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际库区/库位导入模板
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class WmsActualWarehouseImportVo {
|
||||||
|
|
||||||
|
@ExcelProperty("一级编码")
|
||||||
|
private String levelOneCode;
|
||||||
|
|
||||||
|
@ExcelProperty("一级名称")
|
||||||
|
private String levelOneName;
|
||||||
|
|
||||||
|
@ExcelProperty("一级排序号")
|
||||||
|
private Long levelOneSort;
|
||||||
|
|
||||||
|
@ExcelProperty("二级编码")
|
||||||
|
private String levelTwoCode;
|
||||||
|
|
||||||
|
@ExcelProperty("二级名称")
|
||||||
|
private String levelTwoName;
|
||||||
|
|
||||||
|
@ExcelProperty("二级排序号")
|
||||||
|
private Long levelTwoSort;
|
||||||
|
|
||||||
|
@ExcelProperty("三级编码")
|
||||||
|
private String levelThreeCode;
|
||||||
|
|
||||||
|
@ExcelProperty("三级名称")
|
||||||
|
private String levelThreeName;
|
||||||
|
|
||||||
|
@ExcelProperty("三级排序号")
|
||||||
|
private Long levelThreeSort;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.klp.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 树形结构视图对象,用于一次性返回三级目录
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WmsActualWarehouseTreeVo extends WmsActualWarehouseVo {
|
||||||
|
|
||||||
|
private List<WmsActualWarehouseTreeVo> children = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.klp.service;
|
package com.klp.service;
|
||||||
|
|
||||||
import com.klp.domain.WmsActualWarehouse;
|
|
||||||
import com.klp.domain.vo.WmsActualWarehouseVo;
|
import com.klp.domain.vo.WmsActualWarehouseVo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseImportVo;
|
||||||
import com.klp.domain.bo.WmsActualWarehouseBo;
|
import com.klp.domain.bo.WmsActualWarehouseBo;
|
||||||
|
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -26,11 +28,26 @@ public interface IWmsActualWarehouseService {
|
|||||||
*/
|
*/
|
||||||
List<WmsActualWarehouseVo> queryList(WmsActualWarehouseBo bo);
|
List<WmsActualWarehouseVo> queryList(WmsActualWarehouseBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询完整的三级目录树
|
||||||
|
*/
|
||||||
|
List<WmsActualWarehouseTreeVo> queryTree(WmsActualWarehouseBo bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增实际库区/库位自关联
|
* 新增实际库区/库位自关联
|
||||||
*/
|
*/
|
||||||
Boolean insertByBo(WmsActualWarehouseBo bo);
|
Boolean insertByBo(WmsActualWarehouseBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过一次提交批量创建/复用三级目录
|
||||||
|
*/
|
||||||
|
List<Long> createHierarchy(WmsActualWarehouseHierarchyBo bo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入层级目录
|
||||||
|
*/
|
||||||
|
void importHierarchy(List<WmsActualWarehouseImportVo> importList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改实际库区/库位自关联
|
* 修改实际库区/库位自关联
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,20 +1,25 @@
|
|||||||
package com.klp.service.impl;
|
package com.klp.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.klp.common.exception.ServiceException;
|
||||||
import com.klp.common.utils.StringUtils;
|
import com.klp.common.utils.StringUtils;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import com.klp.domain.bo.WmsActualWarehouseBo;
|
import com.klp.domain.bo.WmsActualWarehouseBo;
|
||||||
|
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
|
||||||
|
import com.klp.domain.vo.WmsActualWarehouseImportVo;
|
||||||
import com.klp.domain.vo.WmsActualWarehouseVo;
|
import com.klp.domain.vo.WmsActualWarehouseVo;
|
||||||
import com.klp.domain.WmsActualWarehouse;
|
import com.klp.domain.WmsActualWarehouse;
|
||||||
import com.klp.mapper.WmsActualWarehouseMapper;
|
import com.klp.mapper.WmsActualWarehouseMapper;
|
||||||
import com.klp.service.IWmsActualWarehouseService;
|
import com.klp.service.IWmsActualWarehouseService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实际库区/库位自关联Service业务层处理
|
* 实际库区/库位自关联Service业务层处理
|
||||||
@@ -46,6 +51,36 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<WmsActualWarehouseTreeVo> queryTree(WmsActualWarehouseBo bo) {
|
||||||
|
if (bo == null) {
|
||||||
|
bo = new WmsActualWarehouseBo();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<WmsActualWarehouse> wrapper = Wrappers.lambdaQuery();
|
||||||
|
wrapper.eq(StringUtils.isNotBlank(bo.getActualWarehouseCode()), WmsActualWarehouse::getActualWarehouseCode, bo.getActualWarehouseCode());
|
||||||
|
wrapper.like(StringUtils.isNotBlank(bo.getActualWarehouseName()), WmsActualWarehouse::getActualWarehouseName, bo.getActualWarehouseName());
|
||||||
|
wrapper.eq(bo.getActualWarehouseType() != null, WmsActualWarehouse::getActualWarehouseType, bo.getActualWarehouseType());
|
||||||
|
wrapper.eq(bo.getIsEnabled() != null, WmsActualWarehouse::getIsEnabled, bo.getIsEnabled());
|
||||||
|
wrapper.orderByAsc(WmsActualWarehouse::getSortNo, WmsActualWarehouse::getActualWarehouseId);
|
||||||
|
List<WmsActualWarehouseVo> flatList = baseMapper.selectVoList(wrapper);
|
||||||
|
Map<Long, WmsActualWarehouseTreeVo> nodeMap = new LinkedHashMap<>();
|
||||||
|
flatList.forEach(item -> {
|
||||||
|
WmsActualWarehouseTreeVo node = new WmsActualWarehouseTreeVo();
|
||||||
|
BeanUtil.copyProperties(item, node);
|
||||||
|
nodeMap.put(node.getActualWarehouseId(), node);
|
||||||
|
});
|
||||||
|
List<WmsActualWarehouseTreeVo> roots = new ArrayList<>();
|
||||||
|
nodeMap.values().forEach(node -> {
|
||||||
|
Long parentId = Optional.ofNullable(node.getParentId()).orElse(0L);
|
||||||
|
if (parentId == 0 || !nodeMap.containsKey(parentId)) {
|
||||||
|
roots.add(node);
|
||||||
|
} else {
|
||||||
|
nodeMap.get(parentId).getChildren().add(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
private LambdaQueryWrapper<WmsActualWarehouse> buildQueryWrapper(WmsActualWarehouseBo bo) {
|
private LambdaQueryWrapper<WmsActualWarehouse> buildQueryWrapper(WmsActualWarehouseBo bo) {
|
||||||
Map<String, Object> params = bo.getParams();
|
Map<String, Object> params = bo.getParams();
|
||||||
LambdaQueryWrapper<WmsActualWarehouse> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<WmsActualWarehouse> lqw = Wrappers.lambdaQuery();
|
||||||
@@ -82,6 +117,80 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
return baseMapper.updateById(update) > 0;
|
return baseMapper.updateById(update) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public List<Long> createHierarchy(WmsActualWarehouseHierarchyBo bo) {
|
||||||
|
if (bo.getLevels() == null || bo.getLevels().isEmpty()) {
|
||||||
|
throw new ServiceException("层级数据不能为空");
|
||||||
|
}
|
||||||
|
List<WmsActualWarehouseHierarchyBo.HierarchyLevel> sortedLevels = bo.getLevels().stream()
|
||||||
|
.sorted(Comparator.comparing(WmsActualWarehouseHierarchyBo.HierarchyLevel::getLevel))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
Long parentId = 0L;
|
||||||
|
List<Long> createdIds = new ArrayList<>();
|
||||||
|
for (WmsActualWarehouseHierarchyBo.HierarchyLevel level : sortedLevels) {
|
||||||
|
Integer levelValue = level.getLevel();
|
||||||
|
if (levelValue == null || levelValue < 1 || levelValue > 3) {
|
||||||
|
throw new ServiceException("层级必须在1-3之间");
|
||||||
|
}
|
||||||
|
if (level.getActualWarehouseId() != null) {
|
||||||
|
WmsActualWarehouse existing = baseMapper.selectById(level.getActualWarehouseId());
|
||||||
|
if (existing == null) {
|
||||||
|
throw new ServiceException("指定的节点不存在:" + level.getActualWarehouseId());
|
||||||
|
}
|
||||||
|
if (!Objects.equals(Optional.ofNullable(existing.getParentId()).orElse(0L), parentId)) {
|
||||||
|
throw new ServiceException("节点不属于当前父级,无法复用");
|
||||||
|
}
|
||||||
|
parentId = existing.getActualWarehouseId();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(level.getActualWarehouseCode()) || StringUtils.isBlank(level.getActualWarehouseName())) {
|
||||||
|
throw new ServiceException("编码与名称不能为空");
|
||||||
|
}
|
||||||
|
WmsActualWarehouse duplicate = baseMapper.selectOne(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||||
|
.eq(WmsActualWarehouse::getParentId, parentId)
|
||||||
|
.and(wrapper -> wrapper.eq(WmsActualWarehouse::getActualWarehouseCode, level.getActualWarehouseCode())
|
||||||
|
.or()
|
||||||
|
.eq(WmsActualWarehouse::getActualWarehouseName, level.getActualWarehouseName())));
|
||||||
|
if (duplicate != null) {
|
||||||
|
parentId = duplicate.getActualWarehouseId();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
WmsActualWarehouse entity = new WmsActualWarehouse();
|
||||||
|
entity.setParentId(parentId);
|
||||||
|
entity.setActualWarehouseType(levelValue.longValue());
|
||||||
|
entity.setActualWarehouseCode(level.getActualWarehouseCode());
|
||||||
|
entity.setActualWarehouseName(level.getActualWarehouseName());
|
||||||
|
entity.setSortNo(Optional.ofNullable(level.getSortNo()).orElse(0L));
|
||||||
|
entity.setIsEnabled(Optional.ofNullable(level.getIsEnabled()).orElse(1));
|
||||||
|
entity.setRemark(level.getRemark());
|
||||||
|
baseMapper.insert(entity);
|
||||||
|
parentId = entity.getActualWarehouseId();
|
||||||
|
createdIds.add(parentId);
|
||||||
|
}
|
||||||
|
return createdIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void importHierarchy(List<WmsActualWarehouseImportVo> importList) {
|
||||||
|
if (CollUtil.isEmpty(importList)) {
|
||||||
|
throw new ServiceException("导入数据不能为空");
|
||||||
|
}
|
||||||
|
for (WmsActualWarehouseImportVo row : importList) {
|
||||||
|
List<WmsActualWarehouseHierarchyBo.HierarchyLevel> levels = new ArrayList<>();
|
||||||
|
appendLevel(levels, 1, row.getLevelOneCode(), row.getLevelOneName(), row.getLevelOneSort());
|
||||||
|
appendLevel(levels, 2, row.getLevelTwoCode(), row.getLevelTwoName(), row.getLevelTwoSort());
|
||||||
|
appendLevel(levels, 3, row.getLevelThreeCode(), row.getLevelThreeName(), row.getLevelThreeSort());
|
||||||
|
if (levels.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
WmsActualWarehouseHierarchyBo bo = new WmsActualWarehouseHierarchyBo();
|
||||||
|
bo.setLevels(levels);
|
||||||
|
createHierarchy(bo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存前的数据校验
|
* 保存前的数据校验
|
||||||
*/
|
*/
|
||||||
@@ -89,6 +198,23 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
//TODO 做一些数据校验,如唯一约束
|
//TODO 做一些数据校验,如唯一约束
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void appendLevel(List<WmsActualWarehouseHierarchyBo.HierarchyLevel> levels,
|
||||||
|
int level,
|
||||||
|
String code,
|
||||||
|
String name,
|
||||||
|
Long sortNo) {
|
||||||
|
if (StringUtils.isBlank(code) || StringUtils.isBlank(name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WmsActualWarehouseHierarchyBo.HierarchyLevel item = new WmsActualWarehouseHierarchyBo.HierarchyLevel();
|
||||||
|
item.setLevel(level);
|
||||||
|
item.setActualWarehouseCode(code.trim());
|
||||||
|
item.setActualWarehouseName(name.trim());
|
||||||
|
item.setSortNo(Optional.ofNullable(sortNo).orElse(0L));
|
||||||
|
item.setIsEnabled(1);
|
||||||
|
levels.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除实际库区/库位自关联
|
* 批量删除实际库区/库位自关联
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class WmsCoilPendingActionServiceImpl implements IWmsCoilPendingActionSer
|
|||||||
qw.eq(bo.getCoilId() != null, "wcpa.coil_id", bo.getCoilId());
|
qw.eq(bo.getCoilId() != null, "wcpa.coil_id", bo.getCoilId());
|
||||||
qw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), "wcpa.current_coil_no", bo.getCurrentCoilNo());
|
qw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), "wcpa.current_coil_no", bo.getCurrentCoilNo());
|
||||||
qw.eq(bo.getActionType() != null, "wcpa.action_type", bo.getActionType());
|
qw.eq(bo.getActionType() != null, "wcpa.action_type", bo.getActionType());
|
||||||
qw.eq(bo.getActionStatus() != null, "wcpa.action_status", bo.getActionStatus());
|
qw.ne(bo.getActionStatus() != null, "wcpa.action_status",2);
|
||||||
qw.eq(bo.getWarehouseId() != null, "wcpa.warehouse_id", bo.getWarehouseId());
|
qw.eq(bo.getWarehouseId() != null, "wcpa.warehouse_id", bo.getWarehouseId());
|
||||||
qw.eq(bo.getPriority() != null, "wcpa.priority", bo.getPriority());
|
qw.eq(bo.getPriority() != null, "wcpa.priority", bo.getPriority());
|
||||||
qw.like(StringUtils.isNotBlank(bo.getSourceType()), "wcpa.source_type", bo.getSourceType());
|
qw.like(StringUtils.isNotBlank(bo.getSourceType()), "wcpa.source_type", bo.getSourceType());
|
||||||
|
|||||||
Reference in New Issue
Block a user