daShangDao_miniProgram/pkgManage/shelf/management.vue
2026-06-15 16:37:57 +08:00

832 lines
18 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="warehouse-select-container">
<view class="header">
<view class="title-container">
<text class="title">货架管理</text>
<text class="subtitle">请选择您要操作的货区</text>
</view>
</view>
<!-- 仓库列表 -->
<view class="warehouse-list">
<view v-if="loading" class="loading">
<text>加载中...</text>
</view>
<view v-else-if="warehouses.length === 0" class="empty-state">
<text>暂无可用一级货区</text>
</view>
<view v-else>
<view v-for="(warehouse, index) in warehouses" :key="warehouse.id" class="warehouse-item">
<!-- 整行可点击区域,除了展开按钮 -->
<view class="warehouse-row" >
<view class="warehouse-info">
<text class="warehouse-name">{{ warehouse.name + warehouse.unit}}</text>
</view>
<view class="warehouse-action">
<view class="warehouse-arrow">
<text class="arrow">></text>
</view>
<!-- 阻止点击展开按钮时触发整行的点击事件 -->
<view class="expand-btn" @click.stop="toggleExpand(warehouse, index)">
<text class="expand-icon">{{ warehouse.expanded ? '收起' : '展开' }}</text>
</view>
</view>
</view>
<!-- 二级货架 -->
<view v-if="warehouse.expanded" class="sub-shelves">
<view class="sub-header">
<text class="sub-title">二级货架</text>
</view>
<view v-if="warehouse.loadingShelves" class="loading-sub">加载中...</view>
<view v-else-if="warehouse.shelves && warehouse.shelves.length === 0" class="empty-sub">暂无二级货架</view>
<view v-else>
<view v-for="(shelf, shelfIndex) in warehouse.shelves" :key="shelf.id" class="shelf-item">
<view class="shelf-row">
<view class="shelf-info">
<text class="shelf-name">{{ shelf.name }}</text>
</view>
<view class="shelf-action">
<view class="expand-btn" @click="toggleExpandShelf(warehouse, index, shelf, shelfIndex)">
<text class="expand-icon">{{ shelf.expanded ? '收起' : '展开' }}</text>
</view>
</view>
</view>
<!-- 三级货架 -->
<view v-if="shelf.expanded" class="freight-shelves">
<view class="sub-header">
<text class="sub-title">三级货架</text>
</view>
<view v-if="shelf.loadingFreights" class="loading-sub">加载中...</view>
<view v-else-if="shelf.freights && shelf.freights.length === 0" class="empty-sub">暂无三级货架</view>
<view v-else>
<view v-for="freight in shelf.freights" :key="freight.id" class="freight-item" @click="navigateToGoodsManagement(warehouse, shelf, freight)">
<view class="freight-info">
<text class="freight-name">{{ freight.name }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
warehouses: [],
loading: true,
phoneNumber: '',
userName: '',
userId: '', // 添加userId字段
// 添加编辑表单数据
editForm: {
id: '',
name: '',
sheQuantityMax: '',
code: '',
status: '0',
address: '',
manager: '',
remark: '',
unit: '库' // 添加单位字段
},
// 二级货架编辑表单数据
editShelfForm: {
id: '',
depotId: '',
depotName: '',
name: '',
code: '',
},
// 二级货架新增表单数据
addShelfForm: {
depotId: '',
depotName: '',
name: '',
code: '',
},
// 三级货架新增表单数据
addFreightForm: {
sheId: '',
sheName: '',
name: '',
code: '',
depotId: '',
},
// 三级货架编辑表单数据
editFreightForm: {
id: '',
sheId: '',
sheName: '',
name: '',
code: '',
depotId: '',
},
showUnitDropdown: false, // 控制单位下拉框显示
unitOptions: ['库', '区', '架', '层', '位'], // 单位选项
currentWarehouseIndex: -1, // 当前编辑的一级货区索引
currentShelfIndex: -1, // 当前编辑的二级货架索引
};
},
onLoad() {
// 从本地存储获取手机号和用户ID
this.phoneNumber = uni.getStorageSync('phoneNumber');
this.userId = uni.getStorageSync('userId'); // 获取用户ID
if (!this.phoneNumber) {
uni.showToast({
title: '登录信息无效,请重新登录',
icon: 'none'
});
uni.redirectTo({
url: '/pages/login/index'
});
return;
}
// 加载仓库列表
this.fetchWarehouses();
},
methods: {
// 获取仓库列表
async fetchWarehouses() {
try {
console.log('开始获取仓库列表,手机号:', this.phoneNumber);
this.loading = true;
const [err, response] = await uni.request({
url: 'https://api.buzhiyushu.cn/shelves/shelves/namelist',
method: 'GET',
data: {
phoneNumber: this.phoneNumber
}
});
console.log("response111", response)
this.loading = false;
if (err) {
console.error('请求发生错误:', err);
uni.showToast({
title: '获取仓库列表失败',
icon: 'none'
});
return;
}
console.log('API响应完整数据:', response);
if (!response || !response.data) {
console.error('响应数据为空');
uni.showToast({
title: '获取仓库列表失败',
icon: 'none'
});
return;
}
console.log('响应数据:', response.data);
if (!response.data.rows) {
console.error('rows数据为空');
uni.showToast({
title: '暂无可用仓库',
icon: 'none'
});
return;
}
// 初始化仓库数据添加expanded属性
this.warehouses = (response.data.rows || []).map(warehouse => {
return {
...warehouse,
expanded: false,
shelves: [],
loadingShelves: false
};
});
console.log('解析后的仓库数据:', this.warehouses);
} catch (error) {
console.error('获取仓库列表失败:', error);
this.loading = false;
uni.showToast({
title: '获取仓库列表失败',
icon: 'none'
});
}
},
// 展开/收起一级货区
async toggleExpand(warehouse, index) {
// 切换展开状态
this.$set(this.warehouses[index], 'expanded', !warehouse.expanded);
// 如果是展开且还没有加载过二级货架数据,则加载数据
if (this.warehouses[index].expanded && (!warehouse.shelves || warehouse.shelves.length === 0)) {
await this.fetchShelves(warehouse.id, index);
}
},
// 获取二级货架数据
async fetchShelves(depotId, warehouseIndex) {
try {
this.$set(this.warehouses[warehouseIndex], 'loadingShelves', true);
const [err, response] = await uni.request({
url: 'https://api.buzhiyushu.cn/shelves/shelves/sheNamelist',
method: 'GET',
data: {
depotId: depotId
}
});
this.$set(this.warehouses[warehouseIndex], 'loadingShelves', false);
if (err) {
console.error('获取二级货架失败:', err);
uni.showToast({
title: '获取二级货架失败',
icon: 'none'
});
return;
}
if (!response || !response.data || !response.data.rows) {
console.error('二级货架数据为空');
this.$set(this.warehouses[warehouseIndex], 'shelves', []);
return;
}
// 初始化二级货架数据
const shelves = (response.data.rows || []).map(shelf => {
return {
...shelf,
expanded: false,
freights: [],
loadingFreights: false
};
});
this.$set(this.warehouses[warehouseIndex], 'shelves', shelves);
console.log('二级货架数据:', shelves);
} catch (error) {
console.error('获取二级货架失败:', error);
this.$set(this.warehouses[warehouseIndex], 'loadingShelves', false);
uni.showToast({
title: '获取二级货架失败',
icon: 'none'
});
}
},
// 展开/收起二级货架
async toggleExpandShelf(warehouse, warehouseIndex, shelf, shelfIndex) {
// 切换展开状态
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'expanded', !shelf.expanded);
// 如果是展开且还没有加载过三级货架数据,则加载数据
if (this.warehouses[warehouseIndex].shelves[shelfIndex].expanded &&
(!shelf.freights || shelf.freights.length === 0)) {
await this.fetchFreights(shelf.id, warehouseIndex, shelfIndex);
}
},
// 获取三级货架数据
async fetchFreights(sheId, warehouseIndex, shelfIndex) {
try {
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'loadingFreights', true);
const [err, response] = await uni.request({
url: 'https://api.buzhiyushu.cn/shelves/shelves/freNamelist',
method: 'GET',
data: {
sheId: sheId
}
});
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'loadingFreights', false);
if (err) {
console.error('获取三级货架失败:', err);
uni.showToast({
title: '获取三级货架失败',
icon: 'none'
});
return;
}
if (!response || !response.data || !response.data.rows) {
console.error('三级货架数据为空');
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'freights', []);
return;
}
// 设置三级货架数据
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'freights', response.data.rows || []);
console.log('三级货架数据:', response.data.rows);
} catch (error) {
console.error('获取三级货架失败:', error);
this.$set(this.warehouses[warehouseIndex].shelves[shelfIndex], 'loadingFreights', false);
uni.showToast({
title: '获取三级货架失败',
icon: 'none'
});
}
},
// 跳转到商品管理页面
navigateToGoodsManagement(warehouse, shelf, freight) {
console.log("warehouse",warehouse)
// 构建code参数拼接一级、二级、三级货架的code
const locationCode = `${warehouse.code || ''}${shelf.code || ''}${freight.code || ''}`;
console.log('跳转到商品管理页面', {
warehouseCode: warehouse.code,
shelfCode: shelf.code,
freightCode: freight.code,
combinedCode: locationCode
});
// 跳转到商品管理页面
uni.navigateTo({
url: `/pkgManage/goods/index?code=${encodeURIComponent(locationCode)}`,
success: () => {
console.log('成功跳转到商品管理页面');
},
fail: (err) => {
console.error('跳转商品管理页面失败:', err);
uni.showToast({
title: '页面跳转失败',
icon: 'none'
});
}
});
},
}
};
</script>
<style>
.warehouse-select-container {
padding: 30rpx;
background-color: #f8f8f8;
min-height: 100vh;
}
.header {
margin-bottom: 40rpx;
padding: 20rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.title-container {
flex: 1;
}
.title {
font-size: 40rpx;
font-weight: bold;
color: #333;
display: block;
margin-bottom: 10rpx;
}
.subtitle {
font-size: 28rpx;
color: #666;
display: block;
}
/* 新建按钮样式 */
.add-btn {
display: flex;
align-items: center;
background-color: #007AFF;
color: #fff;
padding: 15rpx 25rpx;
border-radius: 30rpx;
font-size: 28rpx;
}
.add-icon {
font-size: 32rpx;
margin-right: 6rpx;
font-weight: bold;
}
.add-text {
font-size: 28rpx;
}
.warehouse-list {
background-color: #fff;
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.warehouse-item {
padding: 0 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.warehouse-item:last-child {
border-bottom: none;
}
.warehouse-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
position: relative;
}
.warehouse-row:active {
background-color: #f5f5f5;
}
.warehouse-info {
flex: 1;
}
.warehouse-name {
font-size: 32rpx;
color: #333;
margin-bottom: 6rpx;
}
.warehouse-action {
display: flex;
align-items: center;
}
.action-buttons {
display: flex;
margin-right: 15rpx;
}
.action-btn {
padding: 6rpx 12rpx;
margin-right: 10rpx;
border-radius: 6rpx;
font-size: 24rpx;
}
.edit-btn {
background-color: #f0f0f0;
color: #007AFF;
}
.delete-btn {
background-color: #f0f0f0;
color: #FF3B30;
}
.warehouse-arrow {
width: 40rpx;
text-align: right;
margin-right: 20rpx;
}
.arrow {
font-size: 32rpx;
color: #999;
}
.expand-btn {
background-color: #f0f0f0;
padding: 6rpx 16rpx;
border-radius: 20rpx;
}
.expand-icon {
font-size: 24rpx;
color: #666;
}
.loading,
.empty-state {
padding: 60rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
/* 二级货架样式 */
.sub-shelves {
margin-top: 20rpx;
margin-left: 30rpx;
padding: 10rpx;
background-color: #f9f9f9;
border-radius: 8rpx;
}
.sub-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 10rpx 20rpx 10rpx;
border-bottom: 1rpx solid #eee;
}
.sub-title {
font-size: 26rpx;
color: #666;
font-weight: bold;
}
.sub-add-btn {
font-size: 24rpx;
color: #007AFF;
background-color: #f0f0f0;
padding: 6rpx 12rpx;
border-radius: 20rpx;
}
.shelf-item {
padding: 10rpx;
border-bottom: 1rpx solid #eee;
}
.shelf-item:last-child {
border-bottom: none;
}
.shelf-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
}
.shelf-info {
flex: 1;
}
.shelf-name {
font-size: 28rpx;
color: #444;
}
.shelf-action {
display: flex;
align-items: center;
}
/* 三级货架样式 */
.freight-shelves {
width: 100%;
margin-top: 10rpx;
/* margin-left: 30rpx; */
padding: 10rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
}
.freight-item {
padding: 16rpx 10rpx;
border-bottom: 1rpx solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.freight-item:last-child {
border-bottom: none;
}
.freight-info {
flex: 1;
}
.freight-name {
font-size: 26rpx;
color: #555;
}
.freight-action {
display: flex;
align-items: center;
}
.loading-sub, .empty-sub {
padding: 20rpx 0;
text-align: center;
color: #999;
font-size: 24rpx;
}
/* 添加弹窗样式 */
.edit-popup-container {
width: 650rpx;
background-color: #fff;
border-radius: 12rpx;
overflow: hidden;
}
.edit-popup-header {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #f0f0f0;
}
.edit-popup-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.edit-popup-close {
font-size: 40rpx;
color: #999;
padding: 0 10rpx;
}
.edit-popup-content {
padding: 20rpx 30rpx;
max-height: 700rpx;
overflow-y: auto;
}
.edit-form-item {
margin-bottom: 20rpx;
position: relative;
}
.edit-form-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.required:before {
content: '* ';
color: #FF3B30;
}
.edit-form-input {
width: 100%;
height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
box-sizing: border-box;
}
.edit-form-unit {
position: absolute;
right: 20rpx;
top: 40rpx;
font-size: 28rpx;
color: #666;
}
.edit-form-radio {
display: flex;
margin-top: 10rpx;
}
.radio-item {
display: flex;
align-items: center;
margin-right: 40rpx;
}
.radio-circle {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 1rpx solid #ddd;
margin-right: 10rpx;
display: flex;
justify-content: center;
align-items: center;
}
.radio-active {
border-color: #007AFF;
}
.radio-active:after {
content: '';
width: 24rpx;
height: 24rpx;
border-radius: 50%;
background-color: #007AFF;
}
.radio-text {
font-size: 28rpx;
color: #333;
}
.edit-popup-footer {
display: flex;
border-top: 1rpx solid #f0f0f0;
}
.btn-cancel, .btn-confirm {
flex: 1;
height: 90rpx;
line-height: 90rpx;
text-align: center;
font-size: 32rpx;
border: none;
border-radius: 0;
}
.btn-cancel {
background-color: #f5f5f5;
color: #333;
}
.btn-confirm {
background-color: #007AFF;
color: #fff;
}
/* 名称和单位容器样式 */
.name-unit-container {
display: flex;
position: relative;
}
/* 带单位选择器的输入框样式 */
.edit-form-input.with-unit {
flex: 1;
padding-right: 70rpx; /* 为单位选择器留出空间 */
}
/* 单位选择器样式 */
.unit-selector {
position: absolute;
right: 0;
top: 0;
height: 80rpx;
padding: 0 20rpx;
background-color: #f8f8f8;
border-left: 1rpx solid #ddd;
display: flex;
align-items: center;
min-width: 60rpx;
}
.selected-unit {
font-size: 28rpx;
color: #333;
margin-right: 6rpx;
}
.dropdown-icon {
font-size: 24rpx;
color: #666;
}
/* 下拉选项样式 */
.unit-dropdown {
position: absolute;
right: 0;
top: 80rpx;
width: 100rpx;
background-color: #fff;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
z-index: 10;
border: 1rpx solid #eee;
}
.unit-option {
height: 70rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #333;
border-bottom: 1rpx solid #f5f5f5;
}
.unit-option:active,
.unit-option-active {
background-color: #f0f0f0;
color: #007AFF;
}
.unit-option:last-child {
border-bottom: none;
}
</style>