|
|
<template> <div> <div class="pda-container"> <!-- 头部栏 - rqrq --> <div class="header-bar"> <div class="header-left" @click="handleBack"> <i class="el-icon-arrow-left"></i> <span>空托盘组盘</span> </div> <div class="header-right" @click="goHome"> 首页 </div> </div>
<div class="table-body" style="max-height: 600px; overflow-y: auto;"> <div class="main-content form-section"> <!-- 栈板扫描 - rqrq --> <div class="input-group"> <label class="input-label">托盘编码</label> <el-input v-model="palletCode" placeholder="请扫描托盘编码" class="form-input" clearable @keyup.enter.native="handlePalletScan" ref="palletInput" /> </div>
<!-- 托盘信息显示(扫描托盘后显示)- rqrq --> <div v-if="palletScanned" class="pallet-info-section"> <!-- 托盘类型选择 - rqrq --> <div class="input-group"> <label class="input-label">托盘类型</label> <el-select v-model="currentPalletType" placeholder="请选择托盘类型" style="width: 100%;" @change="handlePalletTypeChange" > <el-option v-for="type in palletTypeOptions" :key="type.palletType" :label="`${type.palletType} - ${type.typeDesc}`" :value="type.palletType" /> </el-select> </div>
<div class="input-group"> <label class="input-label">空托数量</label> <el-select v-model="count" disabled> <el-option value=1 label=1></el-option> <el-option value=2 label=2></el-option> <el-option value=3 label=3></el-option> <el-option value=4 label=4></el-option> <el-option value=5 label=5></el-option> <el-option value=6 label=6></el-option> </el-select> </div>
<!-- 当前站点信息 - rqrq --> <div class="info-row"> <label class="info-label">当前站点ID:</label> <span class="info-value">{{ palletInfo.currentStationId || '-' }}</span> </div>
<div class="info-row"> <label class="info-label">当前站点编码:</label> <span class="info-value">{{ palletInfo.currentStationCode || '-' }}</span> </div>
<!-- 操作按钮 - rqrq --> <div class="button-row" style="display: flex; gap: 8px; margin-top: 16px;"> <button class="action-btn primary" @click="handleNotifyInbound" :disabled="notifyLoading || !currentPalletType" style="flex: 1;"> {{ notifyLoading ? '处理中...' : '通知入库' }} </button> <button class="action-btn primary" @click="handleInboundAndTransport" :disabled="transportLoading || !currentPalletType" style="flex: 1;"> {{ transportLoading ? '处理中...' : '入库并运输' }} </button> </div> </div> </div> </div> </div>
<!-- 通知入库口选择弹窗:必须明确选择入库口1/2后才允许提交 - rqrq --> <el-dialog title="请选择入库口" :visible.sync="inboundPortDialogVisible" width="90%" :close-on-click-modal="false" :show-close="false" :append-to-body="true" > <div class="input-group"> <label class="input-label">入库口</label> <el-select v-model="selectedInboundPort" placeholder="请选择入库口" style="width: 100%;"> <el-option v-for="option in inboundPortOptions" :key="option.value" :label="option.label" :value="option.value" /> </el-select> </div> <div slot="footer" class="dialog-footer"> <button class="action-btn secondary" @click="cancelInboundPortDialog">取消</button> <button class="action-btn primary" @click="confirmNotifyInbound">确认</button> </div> </el-dialog> </div></template>
<script>import { checkEmptyPallet, getPalletTypes, updatePalletTypeAndAutoSort, notifyEmptyPalletInbound} from '../../../api/haianAutoWarehouse/emptyPalletAssembly'
export default { data() { return { // 海安PDA前端site唯一来源为store用户对象,兼容旧缓存兜底 - rqrq
site: (this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.site) || localStorage.getItem('site'),
// 托盘信息 - rqrq
palletCode: '', palletScanned: false, palletInfo: { currentStationId: '', currentStationCode: '', palletType: '', area: '' },
// 托盘类型 - rqrq
currentPalletType: '', palletTypeOptions: [], count: 1, // 通知入库口选择 - rqrq
inboundPortDialogVisible: false, selectedInboundPort: '', inboundPortOptions: [ { label: '入库口1', value: 'INBOUND_PORT_1' }, { label: '入库口2', value: 'INBOUND_PORT_2' } ], // 加载状态 - rqrq
notifyLoading: false, transportLoading: false }; }, methods: { // 返回上一页并清空页面状态,避免keep-alive导致脏数据残留 - rqrq
handleBack() { this.resetPage(false); this.$router.back(); },
// 回首页前清理状态,保证再次进入页面从干净态开始 - rqrq
goHome() { this.resetPage(false); this.$router.push({ path: '/' }); },
// 扫描托盘 - rqrq
handlePalletScan() { if (!this.palletCode.trim()) { this.$alert('请输入托盘编码', '提示', { confirmButtonText: '确定' }); return; }
checkEmptyPallet({ site: this.site, palletId: this.palletCode }).then(({ data }) => { if (data.code === 0) { // 后端返回正确的6位栈板码,赋值给输入框 - rqrq
this.palletCode = data.row.palletId;
// 托盘信息 - rqrq
this.palletInfo = data.row; this.currentPalletType = data.row.palletType || ''; this.palletScanned = true;
// 根据托盘的palletFamily加载托盘类型选项 - rqrq
this.loadPalletTypes(data.row.palletFamily);
} else { this.$alert(data.msg || '托盘验证失败', '错误', { confirmButtonText: '确定', callback: () => { this.palletCode = ''; this.$nextTick(() => { if (this.$refs.palletInput) { this.$refs.palletInput.focus(); } }); } }); } }).catch(error => { console.error('查询托盘失败:', error); this.$alert(error.message || '查询托盘失败', '错误', { confirmButtonText: '确定', callback: () => { this.palletCode = ''; this.$nextTick(() => { if (this.$refs.palletInput) { this.$refs.palletInput.focus(); } }); } }); }); },
// 加载托盘类型选项(根据palletFamily过滤)- rqrq
loadPalletTypes(palletFamily) { getPalletTypes({ site: this.site, palletFamily: palletFamily || '' }).then(({ data }) => { if (data.code === 0) { this.palletTypeOptions = data.rows || []; } else { this.palletTypeOptions = []; this.$alert('获取托盘类型失败', '错误', { confirmButtonText: '确定' }); } }).catch(error => { console.error('获取托盘类型失败:', error); this.palletTypeOptions = []; }); },
// 托盘类型变更事件 - rqrq
handlePalletTypeChange() { // 保存到数据库 - rqrq
updatePalletTypeAndAutoSort({ site: this.site, palletId: this.palletCode, palletType: this.currentPalletType, autoSort: 'N', forceFullPalletOut: false }).then(({ data }) => { if (data.code === 0) { this.$message.success('更新成功'); } else { this.$alert(data.msg || '更新失败', '错误', { confirmButtonText: '确定' }); } }).catch(error => { console.error('更新失败:', error); this.$alert(error.message || '更新失败', '错误', { confirmButtonText: '确定' }); }); },
// 通知入库前置校验:仅允许“外部回库”空托盘(area和location_code都为空)继续操作 - rqrq
validateNotifyInboundPalletStatus() { const areaCode = this.palletInfo && this.palletInfo.area ? String(this.palletInfo.area).trim() : '' const locationCode = this.palletInfo && this.palletInfo.locationCode ? String(this.palletInfo.locationCode).trim() : (this.palletInfo && this.palletInfo.currentStationCode ? String(this.palletInfo.currentStationCode).trim() : '') if (areaCode || locationCode) { this.$alert('通知入库仅允许未绑定站点的空托盘', '提示', { confirmButtonText: '确定' }) return false } return true },
// 通知入库 - rqrq
handleNotifyInbound() { if (!this.currentPalletType) { this.$alert('请先选择托盘类型', '提示', { confirmButtonText: '确定' }); return; } if (!this.validateNotifyInboundPalletStatus()) { return; } // 左按钮“通知入库”必须先选入库口,后端再把入库口映射为固定站点号 - rqrq
this.selectedInboundPort = ''; this.inboundPortDialogVisible = true; },
// 关闭入库口弹窗并清理选择状态,避免上次选择串到本次提交 - rqrq
cancelInboundPortDialog() { this.inboundPortDialogVisible = false; this.selectedInboundPort = ''; },
// 确认通知入库:先校验入库口,再调用通知入库接口 - rqrq
confirmNotifyInbound() { if (!this.selectedInboundPort) { this.$alert('请选择入库口', '提示', { confirmButtonText: '确定' }); return; } if (!this.validateNotifyInboundPalletStatus()) { return; } this.inboundPortDialogVisible = false; this.$confirm('确定要执行通知入库操作吗?', '确认操作', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.notifyLoading = true;
notifyEmptyPalletInbound({ site: this.site, palletId: this.palletCode, transportFlag: 'N', count: Number(this.count), inboundPort: this.selectedInboundPort, }).then(({ data }) => { if (data && data.code === 0) { this.$message.success('通知入库成功'); // 清空页面重新扫描 - rqrq
this.resetPage(true); } else { this.$alert(data.msg || '通知入库失败', '错误', { confirmButtonText: '确定' }); } }).catch(error => { console.error('通知入库失败:', error); this.$alert(error.message || '通知入库失败', '错误', { confirmButtonText: '确定' }); }).finally(() => { this.notifyLoading = false; }); }).catch(() => { // 用户取消操作,不提交通知入库 - rqrq
}); },
// 入库并运输 - rqrq
handleInboundAndTransport() { if (!this.currentPalletType) { this.$alert('请先选择托盘类型', '提示', { confirmButtonText: '确定' }); return; } // 右按钮“入库并运输”前置校验:栈板必须绑定area,否则当前位置禁止空托入库 - rqrq
if (!this.palletInfo.area || !String(this.palletInfo.area).trim()) { this.$alert('当前位置不允许空托入库', '提示', { confirmButtonText: '确定' }); return; }
this.$confirm('确定要执行入库并运输操作吗?', '确认操作', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.transportLoading = true;
notifyEmptyPalletInbound({ site: this.site, palletId: this.palletCode, transportFlag: 'Y', count: Number(this.count), }).then(({ data }) => { if (data && data.code === 0) { this.$message.success('入库并运输成功'); // 清空页面重新扫描 - rqrq
this.resetPage(true); } else { this.$alert(data.msg || '入库并运输失败', '错误', { confirmButtonText: '确定' }); } }).catch(error => { console.error('入库并运输失败:', error); this.$alert(error.message || '入库并运输失败', '错误', { confirmButtonText: '确定' }); }).finally(() => { this.transportLoading = false; }); }).catch(() => { // 用户取消操作
}); },
// 重置页面并按需恢复扫码焦点,统一海安PDA页面生命周期清理行为 - rqrq
resetPage(needFocus) { this.palletCode = ''; this.palletScanned = false; this.palletInfo = { currentStationId: '', currentStationCode: '', palletType: '', area: '' }; this.currentPalletType = ''; this.palletTypeOptions = []; this.count = 1; this.inboundPortDialogVisible = false; this.selectedInboundPort = '';
if (needFocus) { this.$nextTick(() => { if (this.$refs.palletInput) { this.$refs.palletInput.focus(); } }); } } }, mounted() { this.$nextTick(() => { if (this.$refs.palletInput) { this.$refs.palletInput.focus(); } }); }, activated() { this.resetPage(true); }, beforeRouteLeave(to, from, next) { this.resetPage(false); next(); }};</script>
<style scoped>/* 托盘信息区域 - rqrq */.pallet-info-section { margin-top: 16px; padding: 12px; background: #f5f7fa; border-radius: 6px;}
.info-row { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #e4e7ed;}
.info-row:last-child { border-bottom: none;}
.info-label { font-weight: bold; color: #606266; width: 120px; flex-shrink: 0;}
.info-value { color: #303133; font-size: 14px;}
.button-row { margin-top: 12px;}</style>
|