Files
FT517-WMS/RuoYi-App-master/pages/out/bindShell.vue
2025-09-11 14:29:56 +08:00

643 lines
14 KiB
Vue
Raw 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="container">
<view class="header">
<text class="title">{{ $t('outbound.bindShelf.materialInfo') }}</text>
</view>
<view class="warehouse-select">
<uni-data-select
v-model="selectedWarehouse"
:localdata="warehouseList"
:clear="false"
:placeholder="$t('outbound.bindShelf.selectWarehouse')"
@change="handleWarehouseChange"
/>
</view>
<view class="exit-select" v-if="showExitSelect">
<uni-data-select
v-model="selectedExit"
:localdata="exitList"
:clear="false"
:placeholder="$t('outbound.bindShelf.selectExit')"
@change="handleExitChange"
/>
</view>
<view class="loading-container" v-if="loading">
<text class="loading-text">{{ $t('outbound.bindShelf.loading') }}</text>
</view>
<view class="materials-list" v-else-if="materialList.length > 0">
<view v-for="(item, index) in materialList" :key="index" class="material-card">
<view class="material-header">
<view class="select-container">
<checkbox :checked="item.selected" @click="toggleSelect(index)" />
</view>
<view class="material-info">
<view class="material-title">{{ item.productName }}</view>
<view class="material-code">{{ $t('outbound.bindShelf.materialInfo') }}: {{ item.productId }}</view>
</view>
</view>
<view class="material-content">
<view class="quantity-control">
<text class="quantity-label">{{ $t('outbound.bindShelf.bindQuantity') }}</text>
<input
type="number"
v-model="item.bindQuantity"
@input="handleQuantityChange(index)"
class="quantity-input"
/>
</view>
</view>
</view>
</view>
<view v-else class="no-data">
<text>{{ $t('outbound.bindShelf.noMaterialInfo') }}</text>
</view>
<view class="button-group">
<button class="bind-button" @click="openBindShelfPopup">{{ $t('outbound.bindShelf.bindShelf') }}</button>
</view>
<!-- 绑定料架弹窗 -->
<uni-popup ref="bindShelfPopup" type="center">
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">{{ $t('outbound.bindShelf.bindShelfTitle') }}</text>
<text class="popup-close" @click="closeBindShelfPopup">×</text>
</view>
<view class="scan-container">
<view class="input-group">
<input
type="text"
v-model="shelfCode"
:placeholder="$t('outbound.bindShelf.scanShelfCode')"
class="scan-input"
@input="fetchShelfInfo"
@clear="handleClear"
/>
</view>
</view>
<view class="shelf-info" v-if="shelfInfo.length > 0">
<view v-for="(item, index) in shelfInfo" :key="index" class="shelf-item">
<text class="shelf-name">{{ item.productName || $t('outbound.bindShelf.unknownMaterial') }}</text>
<text class="shelf-code">{{ item.productId || $t('outbound.bindShelf.noCode') }}</text>
<text class="shelf-quantity">{{ item.quantity || $t('outbound.bindShelf.noQuantity') }}</text>
</view>
</view>
<view class="popup-footer">
<button class="submit-button" @click="submitBindShelf">{{ $t('outbound.bindShelf.submit') }}</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { sunbmitDeatil, bindDetail,bindShelf } from '@/api/out/productOut.js'
import { getBasWarehouList } from '@/api/bas/bas.js'
export default {
data() {
return {
materialList: [],
loading: false,
shelfCode: '',
shelfInfo: [],
warehouseList: [],
exitListMap: {
'02': [
{ value: "G1004", text: 'G1004' },
{ value: 'G1010', text: 'G1010' },
{ value: 'fluent1', text: 'fluent1' },
{ value: 'fluent2', text: 'fluent2' },
],
'13': [
{ value: 'G2001', text: 'G2001' },
{ value: 'G3001', text: 'G3001' },
{ value: 'G3010', text: 'G3010' },
{ value: 'G4001', text: 'G4001' },
{ value: 'G4010', text: 'G4010' },
{ value: 'G5001', text: 'G5001' },
{ value: 'G5010', text: 'G5010' },
]
},
exitList: [],
selectedWarehouse: '',
selectedExit: '',
showExitSelect: false,
warehouseType: ''
}
},
onLoad() {
// 页面加载时获取仓库列表
this.getWarehouseList()
},
methods: {
// 获取仓库列表
async getWarehouseList() {
try {
const response = await getBasWarehouList({
pageNum: 1,
pageSize: 100
})
if (response.code === 200) {
this.warehouseList = response.rows.map(item => ({
value: item.warehouseId,
text: item.warehouseName,
type: item.warehouseType
}))
// 如果有仓库,默认选择第一个
if (this.warehouseList.length > 0) {
this.selectedWarehouse = this.warehouseList[0].value
this.warehouseType = this.warehouseList[0].type
// 根据仓库类型决定是否显示出口选择
this.showExitSelect = this.warehouseType === '2'
// 根据仓库ID获取对应的出口列表
this.exitList = this.exitListMap[this.selectedWarehouse] || []
// 如果是类型1,直接查询物料信息
if (this.warehouseType === '1') {
this.fetchMaterialData()
} else if (this.warehouseType === '2' && this.exitList.length > 0) {
// 如果是类型2,默认选择第一个出口
this.selectedExit = this.exitList[0].value
this.fetchMaterialData()
}
}
}
} catch (error) {
console.error('获取仓库列表失败:', error)
uni.showToast({
title: '获取仓库列表失败',
icon: 'none'
})
}
},
// 处理仓库选择变更
handleWarehouseChange(value) {
if (!value) return
// 查找选中的仓库信息
const selectedWarehouseInfo = this.warehouseList.find(item => item.value === value)
if (selectedWarehouseInfo) {
this.warehouseType = selectedWarehouseInfo.type
// 根据仓库类型决定是否显示出口选择
this.showExitSelect = this.warehouseType === '2'
// 根据仓库ID获取对应的出口列表
this.exitList = this.exitListMap[value] || []
// 如果是类型1,直接查询物料信息
if (this.warehouseType === '1') {
this.fetchMaterialData()
} else if (this.warehouseType === '2' && this.exitList.length > 0) {
// 如果是类型2,默认选择第一个出口
this.selectedExit = this.exitList[0].value
this.fetchMaterialData()
} else {
// 清空物料列表
this.materialList = []
}
}
},
// 处理出口选择变更
handleExitChange(value) {
if (!value) return
// 当出口选择变更时,重新查询物料信息
this.fetchMaterialData()
},
// 获取物料信息数据
async fetchMaterialData() {
try {
this.loading = true
// 构建查询参数
const params = {
pageSize: 100,
pageNum: 1,
warehouseId: this.selectedWarehouse
}
// 如果是类型2,添加出口参数
if (this.warehouseType === '2' && this.selectedExit) {
params.exitId = this.selectedExit
}
const response = await sunbmitDeatil(params)
if (response && response.code === 200) {
this.materialList = (response.rows || []).map(item => ({
...item,
selected: false,
bindQuantity: item.quantity
}))
} else {
uni.showToast({
title: response.msg || '获取物料信息失败',
icon: 'none'
})
this.materialList = []
}
} catch (error) {
console.error('获取物料信息失败:', error)
uni.showToast({
title: this.$t('outbound.bindShelf.noMaterialInfo'),
icon: 'none'
})
this.materialList = []
} finally {
this.loading = false
}
},
// 切换选择状态
toggleSelect(index) {
this.materialList[index].selected = !this.materialList[index].selected
},
// 处理数量变更
handleQuantityChange(index) {
// 确保输入的是有效数字
const value = this.materialList[index].bindQuantity
if (value === '' || isNaN(Number(value))) {
this.materialList[index].bindQuantity = '0'
} else if (Number(value) < 0) {
this.materialList[index].bindQuantity = '0'
uni.showToast({
title: '绑定数量不能小于0',
icon: 'none'
})
} else if (Number(value) > Number(this.materialList[index].quantit)) {
this.materialList[index].bindQuantity = this.materialList[index].quantit
uni.showToast({
title: '绑定数量不能大于可用数量',
icon: 'none'
})
}
},
// 打开绑定料架弹窗
openBindShelfPopup() {
const selectedItems = this.materialList.filter(item => item.selected)
if (selectedItems.length === 0) {
uni.showToast({
title: '请先选择需要绑定的物料',
icon: 'none'
})
return
}
// 检查绑定数量是否为0或空
const invalidQuantityItem = selectedItems.find(item => {
return !item.bindQuantity || item.bindQuantity === 0
})
if (invalidQuantityItem) {
uni.showToast({
title: '绑定数量不能为0或空',
icon: 'none'
})
return
}
this.$refs.bindShelfPopup.open()
},
// 关闭绑定料架弹窗
closeBindShelfPopup() {
this.$refs.bindShelfPopup.close()
// 清空弹窗数据
this.shelfCode = ''
this.shelfInfo = []
},
handleInput(value) {
if (value) {
this.fetchShelfInfo(value)
}
},
// 处理清除事件
handleClear() {
this.shelfInfo = []
},
// 获取料架信息
async fetchShelfInfo() {
try {
const response = await bindDetail({
containerId: this.shelfCode,
pageSize:100,
pageNum:1
})
uni.hideLoading()
if (response && response.code === 200) {
this.shelfInfo = response.rows || []
if (this.shelfInfo.length === 0) {
uni.showToast({
title: '未找到料架信息',
icon: 'none'
})
}
} else {
uni.showToast({
title: response.msg || '获取料架信息失败',
icon: 'none'
})
}
} catch (error) {
console.error('获取料架信息失败:', error)
uni.hideLoading()
uni.showToast({
title: '获取料架信息失败',
icon: 'none'
})
}
},
// 提交绑定料架
async submitBindShelf() {
if (!this.shelfCode) {
uni.showToast({
title: this.$t('outbound.bindShelf.pleaseScanShelfCode'),
icon: 'none'
})
return
}
const selectedItems = this.materialList.filter(item => item.selected)
if (selectedItems.length === 0) {
uni.showToast({
title: this.$t('outbound.bindShelf.pleaseSelectMaterial'),
icon: 'none'
})
return
}
// 检查绑定数量是否为0或空
const invalidQuantityItem = selectedItems.find(item => {
return !item.bindQuantity || item.bindQuantity === 0
})
if (invalidQuantityItem) {
uni.showToast({
title: '绑定数量不能为0或空',
icon: 'none'
})
return
}
// 这里可以根据实际需求调用相应的API进行提交
// 示例:构建提交数据
const submitData = {
containerCode: this.shelfCode,
warehouseId:this.selectedWarehouse,
exitId:this.selectedExit,
mydoJobDetailList: selectedItems.map(item => ({
productId: item.productId,
extraField:{
materialDesc: item.productName
},
pickBindQuantity: item.bindQuantity
}))
}
const response = await bindShelf(submitData)
if (response && response.code === 200) {
uni.showToast({
title: '绑定成功',
icon: 'success'
})
this.closeBindShelfPopup()
this.fetchMaterialData()
} else {
uni.showToast({
title: response.msg || '绑定失败',
icon: 'none'
})
}
}
}
}
</script>
<style>
.container {
padding: 20rpx;
}
.header {
margin-bottom: 20rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
}
.warehouse-select,
.exit-select {
margin-bottom: 20rpx;
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
height: 200rpx;
}
.loading-text {
font-size: 28rpx;
color: #666;
}
.materials-list {
margin-top: 20rpx;
}
.material-card {
background-color: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
margin-bottom: 20rpx;
padding: 20rpx;
}
.material-header {
display: flex;
align-items: center;
margin-bottom: 16rpx;
}
.select-container {
margin-right: 20rpx;
}
.material-info {
flex: 1;
}
.material-title {
font-size: 30rpx;
font-weight: bold;
margin-bottom: 8rpx;
}
.material-code {
font-size: 26rpx;
color: #666;
}
.material-content {
padding: 10rpx 0;
}
.quantity-control {
display: flex;
align-items: center;
}
.quantity-label {
font-size: 28rpx;
margin-right: 20rpx;
}
.quantity-input {
width: 120rpx;
height: 60rpx;
border: 1px solid #ddd;
border-radius: 6rpx;
text-align: center;
font-size: 28rpx;
}
.no-data {
display: flex;
justify-content: center;
align-items: center;
height: 200rpx;
color: #999;
font-size: 28rpx;
}
.button-group {
margin-top: 30rpx;
display: flex;
justify-content: center;
}
.bind-button {
background-color: #007aff;
color: #fff;
font-size: 30rpx;
padding: 20rpx 60rpx;
border-radius: 8rpx;
}
.popup-content {
background-color: #fff;
border-radius: 12rpx;
width: 600rpx;
padding: 30rpx;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.popup-title {
font-size: 32rpx;
font-weight: bold;
}
.popup-close {
font-size: 40rpx;
color: #999;
}
.scan-container {
margin-bottom: 30rpx;
}
.input-group {
display: flex;
align-items: center;
}
.scan-input {
flex: 1;
height: 80rpx;
border: 1px solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
}
.scan-button {
margin-left: 20rpx;
background-color: #007aff;
color: #fff;
font-size: 28rpx;
padding: 0 30rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 8rpx;
}
.shelf-info {
margin-bottom: 30rpx;
max-height: 300rpx;
overflow-y: auto;
}
.shelf-item {
padding: 20rpx;
border-bottom: 1px solid #eee;
}
.shelf-name {
font-size: 28rpx;
font-weight: bold;
display: block;
margin-bottom: 10rpx;
}
.shelf-code {
font-size: 24rpx;
color: #666;
display: block;
}
.popup-footer {
display: flex;
justify-content: center;
}
.submit-button {
background-color: #007aff;
color: #fff;
font-size: 30rpx;
padding: 20rpx 60rpx;
border-radius: 8rpx;
}
</style>