<template> <div> <div class="area-code">{{ selected.join(', ') }}</div> <el-button v-show="!readonly" type="primary" size="mini" @click="handleOpen">选择</el-button> <el-dialog title="储位" :visible.sync="dialogVisible" width="30%" append-to-body :before-close="handleClose"> <el-tabs v-model="activeName" type="card" @tab-click="activeWarehouse = {}"> <el-tab-pane :label="item.name" :name="'' + index" v-for="(item, index) in area" :key="index"> <div> <div style="text-align: center">{{$t('区域')}}</div> <div style="background-color: #efefef;padding: 10px 10px 0;border: #dcdcdc solid 1px;border-radius: 2px"> <el-row :gutter="20"> <el-col :span="12" v-for="warehouse in item.children" :key="warehouse.id"> <div class="warehouse-block" :class="{'warehouse-block-selected': warehouse.selected, 'warehouse-block-active': warehouse.id === activeWarehouse.id}" @click="handleSelectWarehouse(warehouse)" > {{ warehouse.name }} </div> </el-col> </el-row> </div> </div> <div> <div style="text-align: center">{{$t('仓位')}}</div> <div class="position-group"> <div class="position" v-for="position in activeWarehouse.positionList" :key="position.id" @click="handleSelectPosition(position)"> <template v-if="position.children"> <div class="position-item" v-for="item in position.children" :key="item.id" @click.stop="handleSelectPositionChild(item)" :class="{'position-item-active': item.selected}"> {{ item.code }} </div> </template> <template v-else> <div class="position-item" :class="{'position-item-active': position.selected}"> {{ position.code }} </div> </template> </div> </div> </div> <el-divider></el-divider> {{$t('已选择')}}:{{ selected.join(', ') }} <el-divider></el-divider> </el-tab-pane> </el-tabs> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="handleSave">确 定</el-button> </span> </el-dialog> </div> </template> <script> import {getByWarehouseId} from "@/api/ecw/warehouseArea" import { updateWarehouseInLocation } from "@/api/ecw/order" export default { name: "WarehouseAreaSelect", props: { value: { type: Array, default: () => [] }, orderId: Number, orderItemId: Number, // 入仓记录id warehouseInId: Number, warehouseId: { type: Number, default: undefined }, // 是否入仓修改 isEditing: { type: Boolean, default: false }, readonly: { type: Boolean, default: false } }, data() { return { dialogVisible: false, activeName: '0', activeWarehouse: {}, area: [], } }, mounted() { this.initArea() }, computed: { // code array selected() { const result = [] this.area?.forEach(e => { // 仓库 e.children?.forEach(f => { // 区域 if (f.selected) result.push(f.code) else f.positionList?.forEach(g => { // 位置 if (g.selected) result.push(f.code + g.code) else if(g.children) g.children?.forEach(k => { // 子位置 if (k.selected) result.push(f.code + k.code) }) }) }) }) return result }, inputValue(){ const result = [] this.area?.forEach(e => { // 仓库 e.children?.forEach(f => { // 区域 if (f.selected) result.push({ orderId: this.orderId, wareId: f.pid, areaId: f.id }) else { f.positionList?.forEach(g => { // 位置 if (g.selected) result.push({ orderId: this.orderId, wareId: g.domainId, areaId: g.areaId, locationId: g.id }) else g.children?.forEach(k => { // 子位置 if (k.selected) result.push({ orderId: this.orderId, wareId: k.domainId, areaId: k.areaId, locationId: k.id }) }) }) } }) }) return result } }, methods: { handleOpen(){ this.dialogVisible = true // this.initArea() }, handleSave(){ this.$nextTick(() => { const data = this.inputValue.map(e => { return { ...e, orderItemId: this.orderItemId, warehouseInId: this.warehouseInId } }) this.$emit('input', data) this.dialogVisible = false if (this.isEditing || this.warehouseInId) { updateWarehouseInLocation(data).then(() => { this.$message.success('储位修改成功') }) } }) }, handleClose() { this.dialogVisible = false }, handleSelectWarehouse(warehouse) { this.activeWarehouse = warehouse if (!!warehouse.selected) { warehouse.selected = false return } else if(this.activeWarehouseId !== warehouse.id) { this.activeWarehouseId = warehouse.id if (this.inputValue.find(e => e.areaId === warehouse.id)){ return } } warehouse.selected = true // 区域被选,清空该区域下的位置 if(warehouse.positionList) warehouse.positionList?.forEach(g => { g.selected = false g.children?.forEach(k => { k.selected = false }) }) }, handleSelectPositionChild(position) { if (!!position.selected) { position.selected = false // 反选位置时,检查父区域下是否所有位置被反选,若是,选父区域 const parentAre = this.area.find(e => e.id === position.domainId).children.find(f => f.id === position.areaId) if (!parentAre.selected) { // 检查父区域下是否所有位置被反选 let hasSelected = false parentAre.positionList?.forEach(g => { // 位置 g.children?.forEach(k => { // 子位置 if (k.selected) hasSelected = true }) }) // 所有子位置被反选,选父区域 if (!hasSelected) parentAre.selected = true } } else { position.selected = true // 选位置时,父区域反选 this.area.find(e => e.id === position.domainId).children.find(f => f.id === position.areaId).selected = false } }, handleSelectPosition(position) { if (!!position.selected) { position.selected = false } else { position.selected = true // 选位置时,父区域反选 this.area.find(e => e.id === position.domainId).children.find(f => f.id === position.areaId).selected = false } }, resetAreaTreeSelected(area) { area.forEach(e => { // 仓库 e.children?.forEach(f => { // 区域 f.selected = this.isSelected(e.id, f.id) if(f.positionList) f.positionList.forEach(g => { // 位置 g.selected = this.isSelected(e.id, f.id, g.id) g.children?.forEach(k => { // 子位置 k.selected = this.isSelected(e.id, f.id, k.id) }) }) }) }) return area }, initArea(){ return getByWarehouseId({ warehouseId: this.warehouseId }).then(r => { this.area = this.resetAreaTreeSelected(r.data) }) }, // 用于储位回显选中 isSelected(warehouse, area, position = 0){ return !!this.value.find(e => warehouse === e.wareId && area === e.areaId && (position === e.locationId || undefined === e.locationId)) }, } } </script> <style scoped> .area-code{ display: inline-block; margin-right: 15px; } .warehouse-block{ background-color: white; border-radius: 5px; height: 42px; line-height: 42px; text-align: center; margin-bottom: 15px; cursor: pointer; transition: 0.5s; box-shadow: #bfbfbf 3px 3px 14px 0; user-select: none; } .warehouse-block:hover{ opacity: 0.9; transition: 0.5s; transform: scale(1.02); box-shadow: #8f8f8f 7px 5px 14px 0; } .warehouse-block-active{ box-shadow: #b1a4cb 7px 5px 14px 0; transform: scale(1.04); background-color: #9ab7e1; color: #ffffff; } .warehouse-block-selected{ color: #ffffff; background-color: #4085e3; } .position-group{ display: flex; background-color: #EFEFEF; border: 1px #EFEFEF solid; gap: 1px; min-height: 64px; flex-flow: wrap; } .position{ width: calc(20% - 1px); height: 64px; display: flex; flex-direction: column; gap: 1px; user-select: none; } .position-item{ width: 100%; background-color: #FFFFFF; flex: 1; cursor: pointer; text-align: center; display: flex; justify-content: center; align-items: center; } .position-item:hover{ background-color: #d7dbe3; } .position-item-active{ background-color: #4085e3; color: white; } .position-item-active:hover{ background-color: #4085e3; opacity: 0.8; } </style>