508 lines
13 KiB
Vue
508 lines
13 KiB
Vue
<template>
|
||
<!-- <view class="form-container"> -->
|
||
<!-- <view class="view-container"> -->
|
||
<view class="view-item view-item-3">
|
||
<view class="label" @click="onLabelClick">货区</view>
|
||
<view class="select" @click="openPicker">
|
||
{{ selectedStorage || '请选择货区' }}
|
||
</view>
|
||
<u-picker :show="showPicker" ref="uPicker" :columns="columns" @cancel="cancelPicker" @confirm="confirmPicker"
|
||
@change="changeHandler"></u-picker>
|
||
</view>
|
||
<!-- </view> -->
|
||
<!-- </view> -->
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'WarehouseSelector',
|
||
props: {
|
||
// 初始选中的货区
|
||
initialStorage: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 原始warehouse对象
|
||
initialWarehouse: {
|
||
type: Object,
|
||
default: null
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
showPicker: false,
|
||
selectedStorage: this.initialStorage,
|
||
warehouse: '',
|
||
shelf: '',
|
||
location: '',
|
||
columns: [
|
||
[], // 仓库列表
|
||
[], // 货架列表
|
||
[] // 货位列表
|
||
],
|
||
shelves: [], // 货架列表
|
||
locations: [], // 货位列表
|
||
selectedWarehouse: null,
|
||
selectedSheId: null,
|
||
selectedFreId: null
|
||
};
|
||
},
|
||
mounted() {
|
||
this.initData();
|
||
this.loadStorageSelection();
|
||
},
|
||
watch: {
|
||
// 监听initialWarehouse变化,重新初始化
|
||
initialWarehouse: {
|
||
handler(newValue) {
|
||
if (newValue) {
|
||
this.selectedWarehouse = newValue;
|
||
this.initData();
|
||
}
|
||
},
|
||
immediate: true
|
||
},
|
||
selectedWarehouse: {
|
||
handler(newVal, oldVal) {
|
||
if (newVal) {
|
||
// 重新拉取货架和货位数据
|
||
this.columns[0] = [newVal.name];
|
||
this.fetchShelves(newVal.id).then(shelves => {
|
||
if (shelves.length > 0) {
|
||
this.columns[1] = shelves.map(item => item.code);
|
||
this.fetchLocations(shelves[0].id).then(locations => {
|
||
this.columns[2] = locations.map(item => item.code);
|
||
|
||
// 在数据加载完成后,尝试加载该仓库的货区状态
|
||
this.$nextTick(() => {
|
||
this.loadStorageSelection();
|
||
});
|
||
});
|
||
} else {
|
||
this.columns[1] = [];
|
||
this.columns[2] = [];
|
||
// 没有货架数据时也要尝试加载货区状态(可能会清空)
|
||
this.$nextTick(() => {
|
||
this.loadStorageSelection();
|
||
});
|
||
}
|
||
});
|
||
|
||
// 如果是仓库切换(不是初始化),先清空当前状态
|
||
if (oldVal && oldVal.id !== newVal.id) {
|
||
console.log(`仓库从${oldVal.id}切换到${newVal.id},清空当前货区状态`);
|
||
this.clearStorageSelection();
|
||
}
|
||
} else {
|
||
// 没有选择仓库时清空状态
|
||
this.clearStorageSelection();
|
||
}
|
||
},
|
||
immediate: true
|
||
}
|
||
},
|
||
methods: {
|
||
// 保存货区选择状态到本地存储
|
||
saveStorageSelection() {
|
||
// 只有在选择了仓库的情况下才保存货区状态
|
||
if (!this.selectedWarehouse || !this.selectedWarehouse.id) {
|
||
console.log('未选择仓库,不保存货区状态');
|
||
return;
|
||
}
|
||
|
||
const storageData = {
|
||
selectedStorage: this.selectedStorage,
|
||
warehouse: this.warehouse,
|
||
shelf: this.shelf,
|
||
location: this.location,
|
||
selectedSheId: this.selectedSheId,
|
||
selectedFreId: this.selectedFreId
|
||
};
|
||
|
||
// 使用仓库ID作为键的一部分,为每个仓库单独保存货区状态
|
||
const storageKey = `selectedStorageData_${this.selectedWarehouse.id}`;
|
||
uni.setStorageSync(storageKey, storageData);
|
||
console.log(`保存仓库${this.selectedWarehouse.id}的货区选择状态:`, storageData);
|
||
},
|
||
|
||
// 从本地存储加载货区选择状态
|
||
loadStorageSelection() {
|
||
try {
|
||
// 只有在选择了仓库的情况下才加载货区状态
|
||
if (!this.selectedWarehouse || !this.selectedWarehouse.id) {
|
||
console.log('未选择仓库,清空货区状态');
|
||
this.clearStorageSelection();
|
||
return;
|
||
}
|
||
|
||
// 根据仓库ID加载对应的货区状态
|
||
const storageKey = `selectedStorageData_${this.selectedWarehouse.id}`;
|
||
const storageData = uni.getStorageSync(storageKey);
|
||
|
||
if (storageData) {
|
||
console.log(`加载仓库${this.selectedWarehouse.id}的货区选择状态:`, storageData);
|
||
this.selectedStorage = storageData.selectedStorage || '';
|
||
this.warehouse = storageData.warehouse || '';
|
||
this.shelf = storageData.shelf || '';
|
||
this.location = storageData.location || '';
|
||
this.selectedSheId = storageData.selectedSheId || null;
|
||
this.selectedFreId = storageData.selectedFreId || null;
|
||
|
||
// 强制更新视图
|
||
this.$forceUpdate();
|
||
} else {
|
||
console.log(`仓库${this.selectedWarehouse.id}没有保存的货区状态,清空当前状态`);
|
||
this.clearStorageSelection();
|
||
}
|
||
} catch (error) {
|
||
console.error('加载货区选择状态失败:', error);
|
||
}
|
||
},
|
||
|
||
// 清空货区选择状态
|
||
clearStorageSelection() {
|
||
this.selectedStorage = '';
|
||
this.warehouse = '';
|
||
this.shelf = '';
|
||
this.location = '';
|
||
this.selectedSheId = null;
|
||
this.selectedFreId = null;
|
||
|
||
// 重置选择器的值
|
||
this.selectedValues = ['', '', ''];
|
||
|
||
// 强制更新视图
|
||
this.$forceUpdate();
|
||
console.log('已清空货区选择状态');
|
||
},
|
||
|
||
// 初始化数据
|
||
async initData() {
|
||
if (this.initialWarehouse) {
|
||
this.selectedWarehouse = this.initialWarehouse;
|
||
|
||
// 设置仓库列
|
||
this.columns[0] = [this.initialWarehouse.name];
|
||
|
||
// 加载货架数据
|
||
if (this.initialWarehouse.id) {
|
||
const shelves = await this.fetchShelves(this.initialWarehouse.id);
|
||
// console.log('初始化货架数据:', shelves);
|
||
|
||
// 如果存在货架数据,加载第一个货架的货位数据
|
||
if (shelves && shelves.length > 0) {
|
||
await this.fetchLocations(shelves[0].id);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
// 更新选中的货区数据
|
||
updateSelectedStorage(data) {
|
||
// console.log('更新货区数据:', data);
|
||
if (data) {
|
||
this.selectedStorage = data.storage;
|
||
this.warehouse = data.warehouse;
|
||
this.shelf = data.shelf;
|
||
this.location = data.location;
|
||
this.selectedSheId = data.shelfId;
|
||
this.selectedFreId = data.locationId;
|
||
|
||
// 强制更新视图
|
||
this.$forceUpdate();
|
||
}
|
||
},
|
||
|
||
// 打开选择器
|
||
openPicker() {
|
||
// 在打开选择器前确保数据已加载
|
||
if (this.columns[0].length === 0 && this.selectedWarehouse) {
|
||
this.columns[0] = [this.selectedWarehouse.name];
|
||
}
|
||
this.showPicker = true;
|
||
},
|
||
|
||
// 点击标签
|
||
onLabelClick() {
|
||
this.$emit('label-click');
|
||
},
|
||
|
||
// 取消选择
|
||
cancelPicker() {
|
||
this.showPicker = false;
|
||
},
|
||
|
||
// 确认选择
|
||
confirmPicker(e) {
|
||
const {
|
||
value
|
||
} = e;
|
||
const [warehouse, shelf, location] = value;
|
||
|
||
// 只有当三个值都存在时才保存选中的值
|
||
if (warehouse && shelf && location) {
|
||
this.warehouse = warehouse;
|
||
this.shelf = shelf;
|
||
this.location = location;
|
||
|
||
// 更新显示文本
|
||
this.selectedStorage = `${warehouse} / ${shelf} / ${location}`;
|
||
|
||
// 查找选中项的ID
|
||
const selectedShelf = this.shelves.find(item => item.code === shelf);
|
||
const selectedLocation = this.locations.find(item => item.code === location);
|
||
|
||
// 保存选中ID
|
||
this.selectedSheId = selectedShelf?.id;
|
||
this.selectedFreId = selectedLocation?.id;
|
||
|
||
// 保存选择状态到本地存储
|
||
this.saveStorageSelection();
|
||
|
||
// 向父组件发送选中数据
|
||
this.$emit('storage-selected', {
|
||
storage: this.selectedStorage,
|
||
warehouse: this.warehouse,
|
||
shelf: this.shelf,
|
||
location: this.location,
|
||
shelfId: this.selectedSheId,
|
||
locationId: this.selectedFreId
|
||
});
|
||
} else {
|
||
// 如果不完整,提示用户
|
||
uni.showToast({
|
||
title: '请完整选择仓库、货架和货位',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
this.showPicker = false;
|
||
},
|
||
|
||
// 处理picker列变化
|
||
async changeHandler(e) {
|
||
// 防御性检查,确保e和必要的属性存在
|
||
if (!e) {
|
||
console.warn('changeHandler: 事件对象为空');
|
||
return;
|
||
}
|
||
|
||
// console.log('选择器变化:', e);
|
||
|
||
// 获取列索引和选中的索引数组
|
||
const {
|
||
columnIndex,
|
||
index
|
||
} = e;
|
||
|
||
// 如果是选择了仓库(第0列)
|
||
if (columnIndex === 0) {
|
||
// 获取选中的仓库
|
||
const warehouseName = this.columns[0][index];
|
||
|
||
// 使用仓库ID获取货架数据
|
||
if (this.selectedWarehouse && this.selectedWarehouse.id) {
|
||
await this.fetchShelves(this.selectedWarehouse.id);
|
||
}
|
||
}
|
||
|
||
// 如果是选择了货架(第1列)
|
||
if (columnIndex === 1 && this.shelves.length > 0) {
|
||
// 获取选中的货架
|
||
const selectedShelf = this.shelves[index];
|
||
// console.log('选中货架:', selectedShelf);
|
||
|
||
// 保存选中的货架ID
|
||
if (selectedShelf && selectedShelf.id) {
|
||
this.selectedSheId = selectedShelf.id;
|
||
await this.fetchLocations(selectedShelf.id);
|
||
}
|
||
}
|
||
},
|
||
|
||
// 获取货架列表
|
||
async fetchShelves(depotId) {
|
||
try {
|
||
// console.log('获取货架数据,仓库ID:', depotId);
|
||
|
||
const response = await uni.request({
|
||
url: 'https://api.buzhiyushu.cn/shelves/shelves/sheNamelist',
|
||
data: {
|
||
depotId
|
||
}
|
||
});
|
||
|
||
// 使用数组解构获取响应结果
|
||
const [err, res] = Array.isArray(response) ? response : [null, response];
|
||
|
||
if (!res?.data?.rows) {
|
||
console.error('获取货架数据失败,返回空数据');
|
||
return [];
|
||
}
|
||
|
||
this.shelves = res.data.rows; // 保存货架列表
|
||
this.columns[1] = this.shelves.map(item => item.code || '未知货架');
|
||
|
||
// console.log('获取到货架数据:', this.shelves);
|
||
// console.log('货架选项:', this.columns[1]);
|
||
|
||
// 更新UI
|
||
this.$nextTick(() => {
|
||
if (this.$refs.uPicker) {
|
||
this.$refs.uPicker.setColumnValues(1, this.columns[1]);
|
||
// 清空货位列
|
||
this.$refs.uPicker.setColumnValues(2, []);
|
||
}
|
||
});
|
||
|
||
return this.shelves;
|
||
} catch (error) {
|
||
console.error('获取货架失败:', error);
|
||
return [];
|
||
}
|
||
},
|
||
|
||
// 获取货位列表
|
||
async fetchLocations(sheId) {
|
||
if (!sheId) {
|
||
console.error('获取货位列表失败:未提供货架ID');
|
||
return [];
|
||
}
|
||
|
||
try {
|
||
// console.log('获取货位数据,货架ID:', sheId);
|
||
|
||
const response = await uni.request({
|
||
url: 'https://api.buzhiyushu.cn/shelves/shelves/freNamelist',
|
||
method: 'GET',
|
||
data: {
|
||
sheId
|
||
}
|
||
});
|
||
|
||
// 使用数组解构获取响应结果
|
||
const [err, res] = Array.isArray(response) ? response : [null, response];
|
||
|
||
if (err) {
|
||
console.error('获取货位请求错误:', err);
|
||
return [];
|
||
}
|
||
|
||
if (!res || !res.data || !res.data.rows) {
|
||
console.error('货位响应数据格式不正确');
|
||
return [];
|
||
}
|
||
|
||
const locations = res.data.rows;
|
||
// console.log('获取到货位数据:', locations);
|
||
|
||
// 保存货位数据
|
||
this.locations = locations;
|
||
|
||
// 更新货位列
|
||
this.columns[2] = locations.map(item => item.code || '未知货位');
|
||
// console.log('货位选项:', this.columns[2]);
|
||
|
||
// 更新UI
|
||
this.$nextTick(() => {
|
||
if (this.$refs.uPicker) {
|
||
this.$refs.uPicker.setColumnValues(2, this.columns[2]);
|
||
}
|
||
});
|
||
|
||
return locations;
|
||
} catch (error) {
|
||
console.error('获取货位列表失败:', error);
|
||
return [];
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
// 监听外部更新事件
|
||
this.$on('storage-selected', this.updateSelectedStorage);
|
||
},
|
||
beforeDestroy() {
|
||
// 移除事件监听
|
||
this.$off('storage-selected', this.updateSelectedStorage);
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
<style scoped>
|
||
.view-container {
|
||
display: flex;
|
||
background-color: #fff;
|
||
margin-bottom: 20rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.view-item {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
/* 垂直居中 */
|
||
padding: 3rpx 0;
|
||
text-align: center;
|
||
color: #666;
|
||
position: relative;
|
||
/* border-bottom: 1px solid #ccc; */
|
||
}
|
||
|
||
.view-item-3 {
|
||
flex: 3 !important;
|
||
}
|
||
|
||
.view-item-4 {
|
||
flex: 4 !important;
|
||
}
|
||
|
||
.view-item-6 {
|
||
flex: 6 !important;
|
||
}
|
||
|
||
.view-item-7 {
|
||
flex: 7 !important;
|
||
}
|
||
|
||
.view-item>.label {
|
||
padding: 0rpx 15rpx;
|
||
text-align: center;
|
||
height: 60rpx;
|
||
line-height: 60rpx;
|
||
color: #000;
|
||
font-size: 28rpx;
|
||
background-color: #ccc;
|
||
border-radius: 8rpx;
|
||
margin-right: 20rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.view-item>.select {
|
||
padding: 16rpx 0rpx;
|
||
text-align: center;
|
||
width: 100%;
|
||
height: 40rpx;
|
||
font-size: 18rpx;
|
||
line-height: 45rpx;
|
||
}
|
||
|
||
.form-container {
|
||
padding-left: 10rpx;
|
||
background-color: #fff;
|
||
}
|
||
|
||
::v-deep .u-picker__view__column__item[class*="data-v-"] {
|
||
font-size: 30rpx !important;
|
||
}
|
||
|
||
/* 确保选择器文本也使用相同大小 */
|
||
.view-item>.select {
|
||
font-size: 23rpx !important;
|
||
}
|
||
|
||
::v-deep .data-v-55c89db1 .u-toolbar__wrapper__confirm.data-v-55c89db1 {
|
||
color: #3c9cff;
|
||
font-size: 45rpx;
|
||
padding: 0 15rpx;
|
||
}
|
||
</style> |