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