fengshang_yangzhou/dev_wms_client/src/layout/pda.vue
Yxq c7eebdab59 新增用户系统
部分bug修复
11月21日
2025-11-21 09:39:38 +08:00

476 lines
14 KiB
Vue

<template>
<el-config-provider :locale="zhCn">
<el-container class="content">
<fieldset class="input-area">
<legend style="font-size: 30px;">PDA拣货系统</legend>
<el-form :model="bindingData" :label-position="labelPosition"
label-width="100px" style="max-width: 100%" :rules="rules" status-icon size="large">
<div class="table-container">
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="箱号:" required>
<el-input class="form-input large-center-input" v-model="bindingData.sourceBox" @keyup.enter="handleSourceBoxEnter" clearable ref="sourceBoxInput"/>
</el-form-item>
</el-col>
<el-col :span="22" :offset="1">
<el-form-item label="物料号:" required>
<el-input class="form-input large-center-input" v-model="bindingData.goodsId" clearable readonly/>
</el-form-item>
</el-col>
<el-col :span="22" :offset="1">
<el-form-item label="跟单信息:" required>
<el-input class="form-input large-center-input" v-model="bindingData.remark" clearable readonly/>
</el-form-item>
</el-col>
<el-col :span="22" :offset="1">
<el-form-item label="本次实际拣选:" required>
<el-input class="form-input large-center-input" v-model="bindingData.planPickQty" clearable/>
</el-form-item>
</el-col>
<el-col :span="22" :offset="1">
<el-form-item label="实际剩余数量:" required>
<el-input class="form-input large-center-input" v-model="bindingData.realRemainQty" clearable/>
</el-form-item>
</el-col>
<el-col :span="22" :offset="1">
<el-form-item label="目标箱号:" required>
<el-input class="form-input large-center-input" v-model="bindingData.containerNo" clearable ref="destinationBoxInput"/>
</el-form-item>
</el-col>
</el-row>
</div>
<br>
<br>
<el-row :gutter="15" class="btn-area">
<el-col :span="8">
<el-form-item>
<el-button type="warning" round @click="resetInput" class="action-button">重置数据</el-button>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" round @click="queryInventory" class="action-button">查询</el-button>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button
type="success"
round
@click="transferBox"
class="action-button">
确认放行
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</fieldset>
<div ref="btnArea"></div>
<!-- 添加全局加载指示器 -->
<div v-if="showLoading" class="loading-overlay">
<div class="loading-spinner">
<i class="el-icon-loading"></i>
<p>处理中...</p>
</div>
</div>
</el-container>
</el-config-provider>
</template>
<script>
import store from '@/store'
import {ElMessage, ElMessageBox} from 'element-plus'
import {confirmCurrentTask, confirmCurrentTaskByPDA, getPdaData} from '@/api/task.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import {queryStocks} from '@/api/stock.js'
import {errorBox, warningBox} from "@/utils/myMessageBox";
import {ref} from "vue";
const USER_NAME = store.getters.getUserName
let pauseGetPickFlag = ref(false)
export default {
name: 'BoxTransfer',
data() {
return {
showLoading: false, // 用于控制全局加载动画的显示
userName: store.getters.getUserName,
bindingData: {
taskId: '',
outType: null,
goodsId: '',
totalNeed: null,
remainNeed: null,
planPickQty: null,
realPickQty: null,
stockId: '',
vehicleId: '',
planRemainQty: null,
realRemainQty: null,
isOut: null,
putArea: '',
warningQty: null,
containerNo: '',
standId: '',
remark: '',
totalQty: '',
isEmpty: ''
},
transferList: [],
inventoryList: [],
labelPosition: "top",
rules: {
sourceBox: [
{ required: true, message: '请输入原始料箱编号' }
],
destinationBox: [
{ required: true, message: '请输入目的料箱编号' }
]
}
}
},
computed: {
zhCn() {
return zhCn;
}
},
mounted() {
this.$refs.sourceBoxInput.focus();
},
methods: {
handleSourceBoxEnter() {
if (this.bindingData.sourceBox) {
this.queryInventory();
// 延迟聚焦到目标箱号输入框,确保查询完成
this.$nextTick(() => {
setTimeout(() => {
this.$refs.destinationBoxInput.focus();
}, 100);
});
}
},
focusDestinationBox() {
this.$refs.destinationBoxInput.focus();
},
focusSourceBox() {
this.$refs.sourceBoxInput.focus();
},
transferBox() {
// 如果正在加载中,防止二次点击
if (this.showLoading) {
return;
}
if (this.bindingData.sourceBox === '' || this.bindingData.containerNo === '') {
ElMessage({
message: '料箱和目的料箱都不能为空',
type: 'error',
});
return;
}
if (this.bindingData.sourceBox === this.bindingData.containerNo) {
ElMessage({
message: '原始料箱和目的料箱不能相同',
type: 'error',
});
return;
}
const request = {
taskConfirm: {
taskId: this.bindingData.taskId,
outType: this.bindingData.outType,
goodsId: this.bindingData.goodsId,
totalNeed: this.bindingData.totalNeed,
remainNeed: this.bindingData.remainNeed,
planPickQty: this.bindingData.planPickQty,
realPickQty: this.bindingData.realPickQty,
containerNo: this.bindingData.containerNo,
totalQty: this.bindingData.totalQty,
isEmpty: this.bindingData.isEmpty
},
stockConfirm: {
stockId: this.bindingData.stockId,
vehicleId: this.bindingData.vehicleId,
goodsId: this.bindingData.goodsId,
planRemainQty: this.bindingData.planRemainQty,
realRemainQty: this.bindingData.realRemainQty,
isOut: this.bindingData.isOut,
putArea: this.bindingData.putArea,
},
standId: this.bindingData.standId,
userName: USER_NAME
}
ElMessageBox.confirm(
`确认将料箱 ${this.bindingData.sourceBox} 转移到 ${this.bindingData.containerNo} 吗?`,
'转移确认'
).then(() => {
// 显示全局加载动画
this.showLoading = true;
confirmCurrentTask(request, { timeout: 15000 }).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
if (responseData.message === "继续拣选"){
ElMessageBox.alert('该料箱还有任务,请继续拣选!', '提示', {
confirmButtonText: '确定',
type: 'info'
});
}
ElMessage({
message: '转移成功',
type: 'success',
});
//this.transferList.push(responseData.data());
this.resetInput();
this.focusSourceBox();
} else {
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '转移失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
ElMessageBox.alert(`请求服务器失败:${err}`, '转移失败', {
type: 'warning',
confirmButtonText: '确定'
})
}).finally(() => {
// 无论成功或失败都关闭加载动画
this.showLoading = false;
})
}).catch(() => {
// 用户取消操作
this.showLoading = false;
})
},
resetInput() {
this.bindingData.sourceBox = '';
this.bindingData.goodsId = '';
this.bindingData.planPickQty = '';
this.bindingData.realRemainQty = '';
this.bindingData.containerNo = '';
this.bindingData.remark = '';
// 重置完成后聚焦到箱号输入框
this.$nextTick(() => {
this.$refs.sourceBoxInput.focus();
});
},
// 查询
queryInventory() {
if (!this.bindingData.sourceBox) {
ElMessage({
message: '请输入箱号进行查询',
type: 'error',
});
return;
}
// 查询
const params = {
containerNo: this.bindingData.sourceBox
}
getPdaData(params).then(res => {
const response = res.data
if (response.code === 0) {
// 检查 data 是否存在且为数组
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
// 取数组中的第一个元素
const result = response.data[0];
this.bindingData.standId = result.childStandId || ''
// 从 taskConfirm 对象中获取数据
if (result.taskConfirm) {
this.bindingData.taskId = result.taskConfirm.taskId || ''
this.bindingData.outType = result.taskConfirm.outType
this.bindingData.goodsId = result.taskConfirm.goodsId || ''
this.bindingData.totalNeed = result.taskConfirm.totalNeed
this.bindingData.remainNeed = result.taskConfirm.remainNeed
this.bindingData.planPickQty = result.taskConfirm.planPickQty
this.bindingData.realPickQty = result.taskConfirm.realPickQty
this.bindingData.containerNo = result.taskConfirm.containerNo || '' // 添加 containerNo
this.bindingData.totalQty = result.taskConfirm.totalQty
this.bindingData.isEmpty = result.taskConfirm.isEmpty
}
// 从 stockConfirm 对象中获取数据
if (result.stockConfirm) {
this.bindingData.stockId = result.stockConfirm.stockId || ''
this.bindingData.vehicleId = result.stockConfirm.vehicleId || ''
this.bindingData.planRemainQty = result.stockConfirm.planRemainQty
this.bindingData.realRemainQty = result.stockConfirm.realRemainQty
this.bindingData.isOut = result.stockConfirm.isOut
this.bindingData.putArea = result.stockConfirm.putArea || ''
this.bindingData.warningQty = result.stockConfirm.warningQty
this.bindingData.remark = result.stockConfirm.remark
}
console.log(this.bindingData)
} else {
ElMessage({
message: '未查询到相关数据',
type: 'warning',
});
}
} else if (response.code === 999) {
// 警告,弹框
pauseGetPickFlag.value = true
warningBox(response.message)
}
}).catch(err => {
console.log(err)
pauseGetPickFlag.value = true
errorBox('请求错误,请检查完原因后刷新界面。')
})
},
}
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.el-row {
margin: 0 0;
}
:deep(.el-form-item__label) {
font-size: 10px;
padding: -5px 0;
}
:deep(.el-select-v2--large .el-select-v2__placeholder) {
font-size: 25px;
}
.el-row .el-form-item {
justify-content: center;
margin-bottom: 10px; /* 减小表单项底部间距 */
}
/* 使用深度选择器更改字体大小 */
:deep(.el-table__body .cell) {
font-size: 10px !important;
}
.el-row .el-form-item .el-select {
width: 100% !important;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.small-label .cell {
font-size: 12px;
}
.input-area {
margin: 0;
width: 800px;
border: solid 1px;
border-radius: 10px;
box-shadow: 0 15px 10px -15px #000;
padding: 20px;
}
/* 新增样式:居中大字体输入框 */
.large-center-input {
text-align: center;
font-size: 24px !important;
}
:deep(.large-center-input .el-input__inner) {
text-align: center;
font-size: 18px !important; /* 减小字体 */
height: 35px; /* 减小高度 */
padding: 0 8px;
}
/* 增加表单标签字体大小 */
:deep(.el-form-item__label) {
font-size: 22px !important;
}
/* 按钮样式 */
.action-button {
width: 100px;
height: 40px;
font-size: 16px;
margin: auto;
}
.el-row .el-form-item .el-button {
width: 100px;
height: 40px;
font-size: 16px;
margin: auto;
}
/* 按钮区域样式 */
.btn-area {
display: flex;
justify-content: center;
align-items: center;
}
:deep(.btn-area .el-col) {
display: flex;
justify-content: center;
}
/* 全局加载动画样式 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
text-align: center;
color: white;
}
.loading-spinner i {
font-size: 48px;
animation: rotating 1s linear infinite;
}
@keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.loading-spinner p {
margin-top: 10px;
font-size: 18px;
}
</style>