Browse Source

运输栈板

dev
常熟吴彦祖 15 hours ago
parent
commit
205b81b04b
  1. 6
      src/api/haianAutoWarehouse/palletChangeStation.js
  2. 1
      src/router/index.js
  3. 6
      src/views/main.vue
  4. 561
      src/views/modules/haianAutoWarehouse/haianPalletChangeStation.vue
  5. 98
      src/views/modules/haianAutoWarehouse/haianPalletPacking.vue
  6. 81
      src/views/modules/haianAutoWarehouse/haianPalletSorting.vue

6
src/api/haianAutoWarehouse/palletChangeStation.js

@ -1,7 +1,13 @@
import { createAPI } from "@/utils/httpRequest.js";
// 海安-检查栈板是否可执行换站(含calling_flag与当前站点)- rqrq
export const checkPalletForChangeStation = data => createAPI(`/haiAnWcsIntegration/checkPalletForChangeStation`, 'post', data)
// 海安-获取可选区域(choose_able=Y)- rqrq
export const getAreaOptionsForChange = data => createAPI(`/haiAnWcsIntegration/getAreaOptionsForChange`, 'post', data)
// 海安-按区域获取站点清单(locationCode/status)- rqrq
export const getStationsByArea = data => createAPI(`/haiAnWcsIntegration/getStationsByArea`, 'post', data)
// 海安-提交托盘运输任务(写haian_wms_order_task并调用立库搬运接口)- rqrq
export const submitChangeStationTask = data => createAPI(`/haiAnWcsIntegration/submitChangeStationTask`, 'post', data)

1
src/router/index.js

@ -153,6 +153,7 @@ const globalRoutes = [
{path: "/haianPalletPacking",name: "haianPalletPacking", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianPalletPacking.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/haianPalletSorting",name: "haianPalletSorting", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianPalletSorting.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/haianPalletSearch",name: "haianPalletSearch", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianPalletSearch.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/haianPalletChangeStation",name: "haianPalletChangeStation", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianPalletChangeStation.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
]

6
src/views/main.vue

@ -151,6 +151,12 @@
</div>
<div class="menu-text">海安查看托盘</div>
</div>
<div class="menu-item" v-site-auth="'54'" @click="navigateWithWarehouseCheck('haianPalletChangeStation')">
<div class="menu-icon purchase">
<van-icon name="shopping-cart-o" size="24" />
</div>
<div class="menu-text">海安托盘运输</div>
</div>
</div>
</div>
<div class="section" v-site-auth="'55'">

561
src/views/modules/haianAutoWarehouse/haianPalletChangeStation.vue

@ -0,0 +1,561 @@
<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="$router.push({ path: '/' })">
首页
</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"
inputmode="none"
autocomplete="off"
autocorrect="off"
spellcheck="false"
ref="palletInput"
/>
</div>
<!-- 栈板信息显示扫描栈板后显示- rqrq -->
<div v-if="palletScanned" class="pallet-info-section">
<!-- 当前站点信息 - 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">
<button class="action-btn primary" @click="showDetailModal" style="width: 100%;">
浏览明细 ({{ detailList.length }})
</button>
</div>
<!-- 选择区域和站点只有栈板未被调用时才显示- rqrq -->
<div v-if="palletInfo.callingFlag !== 'Y'" style="margin-top: 8px">
<!-- 选择区域 - rqrq -->
<div class="input-group">
<label class="input-label">选择区域</label>
<el-select
v-model="selectedArea"
placeholder="请选择区域"
style="width: 100%;"
@change="handleAreaChange"
>
<el-option
v-for="area in areaOptions"
:key="area.areaId"
:label="area.areaDesc"
:value="area.areaId"
/>
</el-select>
</div>
<!-- 选择站点 - rqrq -->
<div class="input-group">
<label class="input-label">选择站点</label>
<el-select
v-model="selectedStation"
placeholder="请选择站点"
style="width: 100%;"
:disabled="!selectedArea"
>
<el-option label="自动分配" value=""></el-option>
<el-option
v-for="station in stationOptions"
:key="station.stationId"
:label="`${station.stationId} (${station.stationCode})`"
:value="station.stationCode"
/>
</el-select>
</div>
<!-- 操作按钮 - rqrq -->
<div class="button-row" style="display: flex; gap: 8px;">
<button class="action-btn secondary" @click="handleReset" style="flex: 1;">
重置
</button>
<button
class="action-btn primary"
@click="handleSubmitTask"
:disabled="submitLoading"
style="flex: 1;">
{{ submitLoading ? '下达中...' : '下达任务' }}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 浏览明细弹窗 - rqrq -->
<el-dialog
:title="'栈板明细 (共' + detailList.length + '条)'"
:visible.sync="detailModalVisible"
width="90%"
:close-on-click-modal="false"
:show-close="false"
:modal="true"
:modal-append-to-body="true"
:append-to-body="true"
>
<div class="table-body" style="max-height: 400px; overflow-y: auto;">
<div class="detail-table">
<div class="table-header">
<div class="col-position">位置</div>
<div class="col-layer">层数</div>
<div class="col-serial">标签号</div>
</div>
<div
v-for="(detail, index) in detailList"
:key="index"
class="table-row"
>
<div class="col-position">{{ detail.position }}</div>
<div class="col-layer">{{ detail.layer }}</div>
<div class="col-serial">{{ detail.serialNo }}</div>
</div>
<div v-if="detailList.length === 0" class="table-row empty-row">
<div class="empty-hint">暂无栈板明细数据</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" @click="detailModalVisible = false">关闭</button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getPalletDetails } from '../../../api/haianAutoWarehouse/palletPacking'
import {
checkPalletForChangeStation,
getAreaOptionsForChange,
getStationsByArea,
submitChangeStationTask
} from '../../../api/haianAutoWarehouse/palletChangeStation'
export default {
name: 'haianPalletChangeStation',
data() {
return {
// - rqrq
palletCode: '',
palletScanned: false,
palletInfo: {
palletId: '',
callingFlag: '',
currentStationId: '',
currentStationCode: ''
},
// - rqrq
selectedArea: '',
selectedStation: '',
areaOptions: [],
stationOptions: [],
// - rqrq
detailList: [],
detailModalVisible: false,
// - rqrq
submitLoading: false
};
},
computed: {
// sitestoresite - rqrq
site() {
const storeSite = this.$store.state.user.site
if (storeSite !== null && storeSite !== undefined && String(storeSite).trim() !== '') {
return String(storeSite).trim()
}
return (localStorage.getItem('site') || '').trim()
}
},
methods: {
// - rqrq
handleBack() {
this.resetPage(false);
this.$router.back();
},
// 退//keep-alive - rqrq
resetPage(needFocus = true) {
this.palletCode = '';
this.palletScanned = false;
this.palletInfo = {
palletId: '',
callingFlag: '',
currentStationId: '',
currentStationCode: ''
};
this.selectedArea = '';
this.selectedStation = '';
this.areaOptions = [];
this.stationOptions = [];
this.detailList = [];
this.detailModalVisible = false;
this.submitLoading = false;
if (needFocus) {
this.$nextTick(() => {
if (this.$refs.palletInput) {
this.$refs.palletInput.focus();
}
});
}
},
// - rqrq
handlePalletScan() {
if (!this.site) {
this.$alert('当前用户缺少site,无法执行海安操作', '提示', {
confirmButtonText: '确定'
});
return;
}
if (!this.palletCode.trim()) {
this.$alert('请输入栈板编码', '提示', {
confirmButtonText: '确定'
});
return;
}
checkPalletForChangeStation({
site: this.site,
palletId: this.palletCode
}).then(({ data }) => {
if (data && data.code === 0 && data.row) {
// R/L - rqrq
this.palletCode = data.row.palletId;
// - rqrq
if (data.row.callingFlag === 'Y') {
this.$alert('栈板被调用,请选择其他栈板', '提示', {
confirmButtonText: '确定',
callback: () => {
this.resetPage(true);
}
});
return;
}
// - rqrq
this.palletInfo = data.row;
this.palletScanned = true;
// - rqrq
this.loadPalletDetails();
// - rqrq
this.loadAreaOptions();
} else {
this.$alert((data && data.msg) || '栈板不存在', '错误', {
confirmButtonText: '确定',
callback: () => {
this.resetPage(true);
}
});
}
}).catch(error => {
console.error('查询栈板失败:', error);
this.$alert((error && error.message) || '查询栈板失败', '错误', {
confirmButtonText: '确定',
callback: () => {
this.resetPage(true);
}
});
});
},
// - rqrq
loadPalletDetails() {
getPalletDetails({
site: this.site,
palletId: this.palletCode,
position: '',
layer: ''
}).then(({ data }) => {
if (data && data.code === 0) {
this.detailList = data.details || [];
} else {
this.detailList = [];
}
}).catch(error => {
console.error('获取栈板明细失败:', error);
this.detailList = [];
});
},
// - rqrq
showDetailModal() {
this.detailModalVisible = true;
},
// - rqrq
loadAreaOptions() {
getAreaOptionsForChange({
site: this.site
}).then(({ data }) => {
if (data && data.code === 0) {
// Z199 - rqrq
const allOptions = data.rows || [];
this.areaOptions = allOptions.filter(area => area.areaId !== 'Z199');
} else {
this.areaOptions = [];
this.$alert('获取区域选项失败', '错误', {
confirmButtonText: '确定'
});
}
}).catch(error => {
console.error('获取区域选项失败:', error);
this.areaOptions = [];
});
},
// - rqrq
handleAreaChange(areaId) {
this.selectedStation = '';
this.stationOptions = [];
if (!areaId) {
return;
}
// locationCode/status - rqrq
getStationsByArea({
site: this.site,
areaId: areaId
}).then(({ data }) => {
if (data && data.code === 0) {
this.stationOptions = data.rows || [];
} else {
this.stationOptions = [];
this.$alert('获取站点选项失败', '错误', {
confirmButtonText: '确定'
});
}
}).catch(error => {
console.error('获取站点选项失败:', error);
this.stationOptions = [];
});
},
// - rqrq
handleReset() {
this.resetPage(true);
},
// - rqrq
handleSubmitTask() {
if (!this.site) {
this.$alert('当前用户缺少site,无法下达任务', '提示', {
confirmButtonText: '确定'
});
return;
}
if (!this.palletInfo.currentStationCode) {
this.$alert('当前站点编码不能为空', '提示', {
confirmButtonText: '确定'
});
return;
}
if (!this.selectedArea) {
this.$alert('请选择目标区域', '提示', {
confirmButtonText: '确定'
});
return;
}
const params = {
site: this.site,
palletId: this.palletCode,
startStation: this.palletInfo.currentStationCode,
targetArea: this.selectedArea,
targetStation: this.selectedStation || '' // - rqrq
};
this.$confirm('确定下达任务?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.submitLoading = true;
submitChangeStationTask(params).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('任务下达成功');
this.resetPage(true);
} else {
this.$alert((data && data.msg) || '任务下达失败', '错误', {
confirmButtonText: '确定'
});
}
}).catch(error => {
console.error('任务下达失败:', error);
this.$alert((error && error.message) || '任务下达失败', '错误', {
confirmButtonText: '确定'
});
}).finally(() => {
this.submitLoading = false;
});
}).catch(() => {
// 便 - rqrq
});
}
},
// keep-alive - rqrq
activated() {
this.resetPage(true);
},
// - rqrq
beforeRouteLeave(to, from, next) {
this.resetPage(false);
next();
},
mounted() {
this.resetPage(true);
}
};
</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;
}
/* 表格样式 - rqrq */
.detail-table {
background: white;
border-radius: 6px;
overflow: hidden;
border: 1px solid #e0e0e0;
}
.table-header,
.table-row {
display: flex;
align-items: center;
padding: 8px;
border-bottom: 1px solid #e0e0e0;
}
.table-header {
background: #f5f5f5;
font-weight: bold;
font-size: 14px;
}
.table-row {
font-size: 13px;
}
.table-row:last-child {
border-bottom: none;
}
.col-position {
flex: 1;
text-align: center;
}
.col-layer {
flex: 1;
text-align: center;
}
.col-serial {
flex: 4;
text-align: center;
word-break: break-all;
}
/* 空数据提示 - rqrq */
.empty-hint {
text-align: center;
color: #999;
padding: 20px;
background: white;
border-radius: 6px;
}
.dialog-footer {
text-align: center;
}
/* 修复模态框层级问题 - rqrq */
::v-deep .el-dialog__wrapper {
z-index: 2000 !important;
}
::v-deep .el-overlay {
z-index: 2000 !important;
}
/* 空数据行样式 - rqrq */
.empty-row {
justify-content: center;
align-items: center;
padding: 20px;
border-bottom: none;
}
.empty-row .empty-hint {
text-align: center;
color: #999;
width: 100%;
}
</style>

98
src/views/modules/haianAutoWarehouse/haianPalletPacking.vue

@ -1,11 +1,11 @@
<template>
<div class="pda-container">
<div class="header-bar">
<div class="header-left" @click="handleBack">
<div class="header-left" :class="{ 'header-action-disabled': interfaceBusy }" @click="handleBack">
<i class="el-icon-arrow-left"></i>
<span>组盘入库</span>
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
<div class="header-right" :class="{ 'header-action-disabled': interfaceBusy }" @click="goHome">首页</div>
</div>
<div class="table-body" style="max-height: 500px; overflow-y: auto;">
@ -31,6 +31,7 @@
class="action-btn secondary"
style="flex: 0.25; margin: 0;"
@click="handleCallPallet"
:disabled="interfaceBusy"
>
Call栈板
</button>
@ -100,6 +101,7 @@
class="action-btn secondary"
style="flex: 0.25; margin: 0; white-space: nowrap;"
@click="refreshTable"
:disabled="interfaceBusy"
>
刷新
</button>
@ -118,7 +120,7 @@
<button
class="action-btn secondary"
style="flex: 0.25; margin: 0; white-space: nowrap;"
:disabled="currentPalletType === ''"
:disabled="interfaceBusy || currentPalletType === ''"
@click="showScanModal"
>
扫描条码
@ -135,10 +137,10 @@
{{ '明细' }}
</button>
</div>
<button class="action-btn warning" style="flex: 0.3; margin: 0;" @click="showScanOutModal" :disabled="scanOutList.length === 0">
<button class="action-btn warning" style="flex: 0.3; margin: 0;" @click="showScanOutModal" :disabled="interfaceBusy || scanOutList.length === 0">
扫出({{ scanOutList.length }})
</button>
<button class="action-btn secondary" style="flex: 0.3; margin: 0;" @click="openTransportModal" :disabled="!currentPalletStation">运输入库</button>
<button class="action-btn secondary" style="flex: 0.3; margin: 0;" @click="openTransportModal" :disabled="interfaceBusy || !currentPalletStation">{{ transportLoading ? '处理中...' : '运输入库' }}</button>
</div>
<div class="list-title" style="flex: 0.5; margin: 0;">
<label style="margin-left: 5px;">条码数:{{ detailList.length }}</label>
@ -192,7 +194,7 @@
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" style="margin-left: 10px;" @click="detailModalVisible = false">取消</button>
<button class="action-btn secondary" style="margin-left: 10px;" @click="detailModalVisible = false" :disabled="interfaceBusy">取消</button>
</div>
</el-dialog>
@ -227,7 +229,7 @@
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" @click="scanOutModalVisible = false">关闭</button>
<button class="action-btn secondary" @click="scanOutModalVisible = false" :disabled="interfaceBusy">关闭</button>
</div>
</el-dialog>
@ -310,7 +312,7 @@
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal">取消</button>
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal" :disabled="interfaceBusy">取消</button>
</div>
</el-dialog>
@ -342,8 +344,8 @@
</el-select>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn primary" @click="submitCallEmpty" :disabled="callEmptyLoading">{{ callEmptyLoading ? '处理中...' : '确认' }}</button>
<button class="action-btn secondary" style="margin-left: 8px;" @click="callEmptyModalVisible = false" :disabled="callEmptyLoading">取消</button>
<button class="action-btn primary" @click="submitCallEmpty" :disabled="interfaceBusy || callEmptyLoading">{{ callEmptyLoading ? '处理中...' : '确认' }}</button>
<button class="action-btn secondary" style="margin-left: 8px;" @click="callEmptyModalVisible = false" :disabled="interfaceBusy || callEmptyLoading">取消</button>
</div>
</el-dialog>
@ -415,7 +417,11 @@ export default {
stationCode: '',
palletType: ''
},
transportLoading: false
transportLoading: false,
// true - rqrq
palletScanLoading: false,
palletConfigLoading: false,
scanRequestLoading: false
}
},
computed: {
@ -441,6 +447,10 @@ export default {
]
}
return this.positionGrid.map((p) => ({ ...p, isPlaceholder: false }))
},
// 退 - rqrq
interfaceBusy() {
return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.callEmptyLoading || this.transportLoading
}
},
methods: {
@ -453,10 +463,20 @@ export default {
return true
},
handleBack() {
if (this.interfaceBusy) {
return
}
// keep-alive - rqrq
this.resetPage(false)
this.$router.back()
},
// - rqrq
goHome() {
if (this.interfaceBusy) {
return
}
this.$router.push({ path: '/' })
},
// 退 - rqrq
resetPage(needFocus = true) {
this.site = this.$store.state.user.site
@ -505,6 +525,9 @@ export default {
palletType: ''
}
this.transportLoading = false
this.palletScanLoading = false
this.palletConfigLoading = false
this.scanRequestLoading = false
if (needFocus) {
this.$nextTick(() => {
if (this.$refs.palletInput) {
@ -517,10 +540,14 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.palletCode || !this.palletCode.trim()) {
this.$alert('请输入栈板编码', '提示', { confirmButtonText: '确定' })
return
}
this.palletScanLoading = true
checkPalletExists({
site: this.site,
palletId: this.palletCode.trim()
@ -541,6 +568,8 @@ export default {
}
}).catch((error) => {
this.$alert(error.message || '栈板校验失败', '错误', { confirmButtonText: '确定' })
}).finally(() => {
this.palletScanLoading = false
})
},
loadPalletInfo() {
@ -654,6 +683,10 @@ export default {
},
// - rqrq
savePalletTypeConfig() {
if (this.interfaceBusy) {
return
}
this.palletConfigLoading = true
updatePalletTypeAndAutoSort({
site: this.site,
palletId: this.palletCode,
@ -668,10 +701,17 @@ export default {
} else {
this.$alert((data && data.msg) || '托盘配置更新失败', '错误', { confirmButtonText: '确定' })
}
}).catch((error) => {
this.$alert(error.message || '托盘配置更新失败', '错误', { confirmButtonText: '确定' })
}).finally(() => {
this.palletConfigLoading = false
})
},
// 沿Call - rqrq
handleCallPallet() {
if (this.interfaceBusy) {
return
}
this.openCallEmptyModal()
},
// PDA - rqrq
@ -815,19 +855,29 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.scanCode || !this.scanCode.trim()) {
this.scanCode = ''
this.$alert('请输入标签编码', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
if (this.operationType === 'in') {
if (!this.scanPosition) {
this.scanCode = ''
this.$alert('请选择位置', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
if (!this.scanLayer) {
this.scanCode = ''
this.$alert('请选择层数', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
this.scanRequestLoading = true
savePalletDetail({
site: this.site,
palletId: this.palletCode,
@ -843,13 +893,20 @@ export default {
this.loadLayerOptions()
this.moveFocusToScanInput()
} else {
this.scanCode = ''
this.$alert((data && data.msg) || '扫进失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}
}).catch((error) => {
this.scanCode = ''
this.$alert(error.message || '扫进失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}).finally(() => {
this.scanRequestLoading = false
})
} else {
const scanOutItem = this.detailList.find((item) => item.serialNo === this.scanCode)
this.scanRequestLoading = true
deletePalletDetail({
site: this.site,
palletId: this.palletCode,
@ -868,10 +925,16 @@ export default {
this.scanCode = ''
this.moveFocusToScanInput()
} else {
this.scanCode = ''
this.$alert((data && data.msg) || '扫出失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}
}).catch((error) => {
this.scanCode = ''
this.$alert(error.message || '扫出失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}).finally(() => {
this.scanRequestLoading = false
})
}
},
@ -917,6 +980,9 @@ export default {
})
},
submitCallEmpty() {
if (this.interfaceBusy) {
return
}
if (!this.callEmptyForm.areaId || !this.callEmptyForm.stationCode || !this.callEmptyForm.palletType) {
this.$alert('请完整选择区域、站点和栈板类型', '提示', { confirmButtonText: '确定' })
return
@ -943,6 +1009,9 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.palletScanned) {
this.$alert('请先扫描栈板', '提示', { confirmButtonText: '确定' })
return
@ -963,7 +1032,7 @@ export default {
})
},
submitTransport() {
if (this.transportLoading) {
if (this.interfaceBusy) {
return
}
this.transportLoading = true
@ -1001,6 +1070,11 @@ export default {
</script>
<style scoped>
.header-action-disabled {
opacity: 0.5;
pointer-events: none;
}
.detail-table {
background: white;
border-radius: 6px;

81
src/views/modules/haianAutoWarehouse/haianPalletSorting.vue

@ -1,11 +1,11 @@
<template>
<div class="pda-container">
<div class="header-bar">
<div class="header-left" @click="handleBack">
<div class="header-left" :class="{ 'header-action-disabled': interfaceBusy }" @click="handleBack">
<i class="el-icon-arrow-left"></i>
<span>人工分拣组盘</span>
</div>
<div class="header-right" @click="$router.push({ path: '/' })">首页</div>
<div class="header-right" :class="{ 'header-action-disabled': interfaceBusy }" @click="goHome">首页</div>
</div>
<div class="table-body" style="max-height: 500px; overflow-y: auto;">
@ -27,7 +27,7 @@
@keyup.enter.native="handlePalletScan"
ref="palletInput"
/>
<button class="action-btn secondary" style="flex: 0.25; margin: 0;" @click="submitFinishSorting" :disabled="finishSortingLoading || detailList.length === 0">
<button class="action-btn secondary" style="flex: 0.25; margin: 0;" @click="submitFinishSorting" :disabled="interfaceBusy || finishSortingLoading || detailList.length === 0">
{{ finishSortingLoading ? '处理中...' : '结束分拣' }}
</button>
</div>
@ -96,6 +96,7 @@
class="action-btn secondary"
style="flex: 0.25; margin: 0; white-space: nowrap;"
@click="refreshTable"
:disabled="interfaceBusy"
>
刷新
</button>
@ -114,7 +115,7 @@
<button
class="action-btn secondary"
style="flex: 0.25; margin: 0; white-space: nowrap;"
:disabled="currentPalletType === ''"
:disabled="interfaceBusy || currentPalletType === ''"
@click="showScanModal"
>
扫描条码
@ -127,12 +128,12 @@
<div v-if="palletScanned" class="rma-list">
<div class="list-title-row" style="display: flex; gap: 8px; align-items: center; padding: 0;">
<div class="list-title" style="flex: 0.75; margin: 0;">
<button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="showDetailModal" :disabled="submitSortingLoading">
<button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="showDetailModal" :disabled="interfaceBusy || submitSortingLoading">
浏览明细
</button>
<label style="margin-left: 5px;">条码数:{{ detailList.length }}</label>
</div>
<button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="submitSorting" :disabled="submitSortingLoading">
<button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="submitSorting" :disabled="interfaceBusy || submitSortingLoading">
{{ submitSortingLoading ? '处理中...' : '提交分拣' }}
</button>
</div>
@ -181,7 +182,7 @@
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" style="margin-left: 10px;" @click="detailModalVisible = false">取消</button>
<button class="action-btn secondary" style="margin-left: 10px;" @click="detailModalVisible = false" :disabled="interfaceBusy">取消</button>
</div>
</el-dialog>
@ -264,7 +265,7 @@
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal">取消</button>
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal" :disabled="interfaceBusy">取消</button>
</div>
</el-dialog>
</div>
@ -328,6 +329,10 @@ export default {
positionGridLoading: false,
submitSortingLoading: false,
finishSortingLoading: false,
// 退 - rqrq
palletScanLoading: false,
palletConfigLoading: false,
scanRequestLoading: false,
}
},
computed: {
@ -353,6 +358,10 @@ export default {
]
}
return this.positionGrid.map((p) => ({ ...p, isPlaceholder: false }))
},
// - rqrq
interfaceBusy() {
return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.submitSortingLoading || this.finishSortingLoading
}
},
methods: {
@ -364,10 +373,20 @@ export default {
return true
},
handleBack() {
if (this.interfaceBusy) {
return
}
// keep-alive - rqrq
this.resetPage(false)
this.$router.back()
},
// - rqrq
goHome() {
if (this.interfaceBusy) {
return
}
this.$router.push({ path: '/' })
},
// 退 - rqrq
resetPage(needFocus = true) {
this.site = this.$store.state.user.site
@ -401,6 +420,9 @@ export default {
this.positionGridLoading = false
this.submitSortingLoading = false
this.finishSortingLoading = false
this.palletScanLoading = false
this.palletConfigLoading = false
this.scanRequestLoading = false
if (needFocus) {
this.$nextTick(() => {
if (this.$refs.palletInput) {
@ -413,10 +435,14 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.palletCode || !this.palletCode.trim()) {
this.$alert('请输入栈板编码', '提示', { confirmButtonText: '确定' })
return
}
this.palletScanLoading = true
checkPalletExists({
site: this.site,
palletId: this.palletCode.trim()
@ -438,6 +464,8 @@ export default {
}
}).catch((error) => {
this.$alert(error.message || '栈板校验失败', '错误', { confirmButtonText: '确定' })
}).finally(() => {
this.palletScanLoading = false
})
},
loadPalletInfo() {
@ -525,12 +553,18 @@ export default {
this.autoSortDisabled = this.detailList.length > 0
},
savePalletTypeConfig() {
if (this.interfaceBusy) {
return
}
this.palletConfigLoading = true
updatePalletTypeAndAutoSort({
site: this.site,
palletId: this.palletCode,
palletType: this.currentPalletType,
autoSort: this.currentAutoSort,
forceFullPalletOut: this.forceFullPalletOut
}).finally(() => {
this.palletConfigLoading = false
})
},
// PDA - rqrq
@ -686,19 +720,29 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.scanCode || !this.scanCode.trim()) {
this.scanCode = ''
this.$alert('请输入标签编码', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
if (this.operationType === 'in') {
if (!this.scanPosition) {
this.scanCode = ''
this.$alert('请选择位置', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
if (!this.scanLayer) {
this.scanCode = ''
this.$alert('请选择层数', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
return
}
this.scanRequestLoading = true
this.loadSortingListIfNeeded()
.then((list) => {
if (list.length === 0) {
@ -748,6 +792,9 @@ export default {
this.scanCode = ''
this.moveFocusToScanInput()
})
.finally(() => {
this.scanRequestLoading = false
})
} else {
const original = this.originalDetailCache[this.scanCode]
if (!original) {
@ -756,6 +803,7 @@ export default {
this.moveFocusToScanInput()
return
}
this.scanRequestLoading = true
restorePalletDetail({
site: this.site,
serialNo: this.scanCode,
@ -774,10 +822,16 @@ export default {
this.scanCode = ''
this.moveFocusToScanInput()
} else {
this.scanCode = ''
this.$alert((data && data.msg) || '分拣扫回失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}
}).catch((error) => {
this.scanCode = ''
this.$alert(error.message || '分拣扫回失败', '错误', { confirmButtonText: '确定' })
this.moveFocusToScanInput()
}).finally(() => {
this.scanRequestLoading = false
})
}
},
@ -785,6 +839,9 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.palletScanned) {
this.$alert('请先扫描栈板', '提示', { confirmButtonText: '确定' })
return
@ -811,6 +868,9 @@ export default {
if (!this.ensureSite()) {
return
}
if (this.interfaceBusy) {
return
}
if (!this.palletScanned) {
this.$alert('请先扫描栈板', '提示', { confirmButtonText: '确定' })
return
@ -849,6 +909,11 @@ export default {
</script>
<style scoped>
.header-action-disabled {
opacity: 0.5;
pointer-events: none;
}
.detail-table {
background: white;
border-radius: 6px;

Loading…
Cancel
Save