8 changed files with 565 additions and 17 deletions
-
14src/api/automatedWarehouse/cancelWcsPallet.js
-
1src/router/index.js
-
6src/views/main.vue
-
76src/views/modules/automatedWarehouse/callOut.vue
-
468src/views/modules/automatedWarehouse/cancelWcsPallet.vue
-
3src/views/modules/automatedWarehouse/emptyPalletAssembly.vue
-
7src/views/modules/automatedWarehouse/palletChangeStation.vue
-
7src/views/modules/automatedWarehouse/palletManualMove.vue
@ -0,0 +1,14 @@ |
|||||
|
import { createAPI } from "@/utils/httpRequest.js"; |
||||
|
|
||||
|
// ========== 取消WCS组盘相关 ========== - rqrq
|
||||
|
|
||||
|
// 检查栈板WCS组盘状态 - rqrq
|
||||
|
export const checkPalletWcsStatus = data => createAPI(`/wcsIntegration/checkPalletWcsStatus`, 'post', data) |
||||
|
|
||||
|
// 取消组盘 - rqrq
|
||||
|
export const cancelWcsPallet = data => createAPI(`/wcsIntegration/cancelWcsPallet`, 'post', data) |
||||
|
|
||||
|
// 移出全部物料 - rqrq
|
||||
|
export const removeAllPalletDetails = data => createAPI(`/wcsIntegration/removeAllPalletDetails`, 'post', data) |
||||
|
|
||||
|
|
||||
@ -0,0 +1,468 @@ |
|||||
|
<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>取消WCS组盘任务</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"> |
||||
|
|
||||
|
<div class="info-row"> |
||||
|
<label class="info-label">是否被调用:</label> |
||||
|
<span class="info-value" :style="{color: palletInfo.callingFlag === 'Y' ? '#F56C6C' : '#67C23A'}"> |
||||
|
{{ palletInfo.callingFlag === 'Y' ? '是' : '否' }} |
||||
|
</span> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 是否发送组盘任务 - rqrq --> |
||||
|
<div class="info-row"> |
||||
|
<label class="info-label">是否已组盘:</label> |
||||
|
<span class="info-value" :style="{color: hasSentWcsTask ? '#F56C6C' : '#67C23A'}"> |
||||
|
{{ hasSentWcsTask ? '是' : '否' }} |
||||
|
</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="showCancelButton" class="button-row"> |
||||
|
<button |
||||
|
class="action-btn primary" |
||||
|
@click="handleCancelWcsPallet" |
||||
|
:disabled="cancelLoading" |
||||
|
style="width: 100%;"> |
||||
|
{{ cancelLoading ? '取消中...' : '取消组盘' }} |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 移出全部物料按钮(只有未发送组盘任务且未被调用且有明细才显示)- rqrq --> |
||||
|
<div v-if="showRemoveAllButton" class="button-row"> |
||||
|
<button |
||||
|
class="action-btn warning" |
||||
|
@click="handleRemoveAllMaterials" |
||||
|
:disabled="removeAllLoading" |
||||
|
style="width: 100%;"> |
||||
|
{{ removeAllLoading ? '移出中...' : '移出全部物料' }} |
||||
|
</button> |
||||
|
</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/automatedWarehouse/palletPacking' |
||||
|
import { |
||||
|
checkPalletWcsStatus, |
||||
|
cancelWcsPallet, |
||||
|
removeAllPalletDetails |
||||
|
} from '../../../api/automatedWarehouse/cancelWcsPallet' |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
site: localStorage.getItem('site'), |
||||
|
|
||||
|
// 栈板信息 - rqrq |
||||
|
palletCode: '', |
||||
|
palletScanned: false, |
||||
|
palletInfo: { |
||||
|
callingFlag: '', |
||||
|
canOperate: '', |
||||
|
isEmpty: '' |
||||
|
}, |
||||
|
|
||||
|
// 按钮显示控制 - rqrq |
||||
|
hasSentWcsTask: false, |
||||
|
showCancelButton: false, |
||||
|
showRemoveAllButton: false, |
||||
|
|
||||
|
// 栈板明细 - rqrq |
||||
|
detailList: [], |
||||
|
detailModalVisible: false, |
||||
|
|
||||
|
// 加载状态 - rqrq |
||||
|
cancelLoading: false, |
||||
|
removeAllLoading: false |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
// 返回上一页 - rqrq |
||||
|
handleBack() { |
||||
|
this.$router.back(); |
||||
|
}, |
||||
|
|
||||
|
// 扫描栈板 - rqrq |
||||
|
handlePalletScan() { |
||||
|
if (!this.palletCode.trim()) { |
||||
|
this.$message.error('请输入栈板编码'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
checkPalletWcsStatus({ |
||||
|
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.palletScanned = true; |
||||
|
|
||||
|
// 解析按钮显示逻辑 - rqrq |
||||
|
// canOperate字段存储showCancelButton(是否显示取消组盘按钮)- rqrq |
||||
|
this.showCancelButton = data.row.canOperate === 'Y'; |
||||
|
|
||||
|
// isEmpty字段存储showRemoveAllButton(是否显示移出全部物料按钮)- rqrq |
||||
|
this.showRemoveAllButton = data.row.isEmpty === 'Y'; |
||||
|
|
||||
|
// 计算hasSentWcsTask(是否发送组盘任务)用于显示 - rqrq |
||||
|
this.hasSentWcsTask = this.showCancelButton; |
||||
|
|
||||
|
// 加载栈板明细 - rqrq |
||||
|
this.loadPalletDetails(); |
||||
|
|
||||
|
} 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(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 加载栈板明细 - rqrq |
||||
|
loadPalletDetails() { |
||||
|
getPalletDetails({ |
||||
|
site: this.site, |
||||
|
palletId: this.palletCode, |
||||
|
position: '', |
||||
|
layer: '' |
||||
|
}).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.detailList = data.details || []; |
||||
|
} else { |
||||
|
this.detailList = []; |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('获取栈板明细失败:', error); |
||||
|
this.detailList = []; |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 显示明细弹窗 - rqrq |
||||
|
showDetailModal() { |
||||
|
this.detailModalVisible = true; |
||||
|
}, |
||||
|
|
||||
|
// 取消组盘 - rqrq |
||||
|
handleCancelWcsPallet() { |
||||
|
this.$confirm('确定要取消组盘吗?取消后需要重新组盘才能推送到WCS。', '确认操作', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.cancelLoading = true; |
||||
|
|
||||
|
cancelWcsPallet({ |
||||
|
site: this.site, |
||||
|
palletId: this.palletCode |
||||
|
}).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
this.$message.success('取消组盘成功'); |
||||
|
// 重新扫描刷新信息 - rqrq |
||||
|
this.handlePalletScan(); |
||||
|
} else { |
||||
|
this.$alert(data.msg || '取消组盘失败', '错误'); |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('取消组盘失败:', error); |
||||
|
this.$message.error(error.message || '取消组盘失败'); |
||||
|
}).finally(() => { |
||||
|
this.cancelLoading = false; |
||||
|
}); |
||||
|
}).catch(() => { |
||||
|
// 用户取消操作 |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
// 移出全部物料 - rqrq |
||||
|
handleRemoveAllMaterials() { |
||||
|
this.$confirm('确定要移出栈板上的全部物料吗?此操作不可恢复!', '确认操作', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.removeAllLoading = true; |
||||
|
|
||||
|
removeAllPalletDetails({ |
||||
|
site: this.site, |
||||
|
palletId: this.palletCode |
||||
|
}).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
this.$message.success('移出全部物料成功'); |
||||
|
// 重新扫描刷新信息 - rqrq |
||||
|
this.handlePalletScan(); |
||||
|
} else { |
||||
|
this.$alert(data.msg || '移出全部物料失败', '错误'); |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('移出全部物料失败:', error); |
||||
|
this.$message.error(error.message || '移出全部物料失败'); |
||||
|
}).finally(() => { |
||||
|
this.removeAllLoading = false; |
||||
|
}); |
||||
|
}).catch(() => { |
||||
|
// 用户取消操作 |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.palletInput) { |
||||
|
this.$refs.palletInput.focus(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
</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: 140px; |
||||
|
flex-shrink: 0; |
||||
|
} |
||||
|
|
||||
|
.info-value { |
||||
|
color: #303133; |
||||
|
font-size: 14px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.button-row { |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
|
||||
|
/* 警告按钮 - rqrq */ |
||||
|
.action-btn.warning { |
||||
|
background-color: #E6A23C; |
||||
|
color: white; |
||||
|
border: none; |
||||
|
padding: 10px 20px; |
||||
|
border-radius: 4px; |
||||
|
cursor: pointer; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.action-btn.warning:hover { |
||||
|
background-color: #d99525; |
||||
|
} |
||||
|
|
||||
|
.action-btn.warning:disabled { |
||||
|
background-color: #f5dab1; |
||||
|
cursor: not-allowed; |
||||
|
} |
||||
|
|
||||
|
/* 表格样式 - 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; |
||||
|
} |
||||
|
|
||||
|
/* 空数据行样式 - 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%; |
||||
|
} |
||||
|
|
||||
|
.dialog-footer { |
||||
|
display: flex; |
||||
|
gap: 8px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
/* 修复模态框层级问题 - rqrq */ |
||||
|
::v-deep .el-dialog__wrapper { |
||||
|
z-index: 2000 !important; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-overlay { |
||||
|
z-index: 2000 !important; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue