shenzhouyu 3 weeks ago
parent
commit
454b5b54c5
  1. 16
      src/api/haianAutoWarehouse/manualCount.js
  2. 2
      src/router/index.js
  3. 6
      src/views/main.vue
  4. 52
      src/views/modules/haianAutoWarehouse/haianCancelWcsPallet.vue
  5. 6
      src/views/modules/haianAutoWarehouse/haianPalletSorting.vue
  6. 660
      src/views/modules/haianAutoWarehouse/manualCount54.vue

16
src/api/haianAutoWarehouse/manualCount.js

@ -0,0 +1,16 @@
import { createAPI } from "@/utils/httpRequest.js";
// 海安PDA手工盘点-扫描栈板,返回盘点单与标签列表 - rqrq
export const pdaScanPallet = data => createAPI(`/autoWareHourceHaian/haiAnPhysicalInventory/pda/scanPallet`, 'post', data)
// 海安PDA手工盘点-扫描标签,返回标签物料与数量信息 - rqrq
export const pdaScanLabel = data => createAPI(`/autoWareHourceHaian/haiAnPhysicalInventory/pda/scanLabel`, 'post', data)
// 海安PDA手工盘点-一键提交托盘盘点结果(默认全部OK)- rqrq
export const pdaQuickSubmitCount = data => createAPI(`/autoWareHourceHaian/haiAnPhysicalInventory/pda/quickSubmitCount`, 'post', data)
// 海安PDA手工盘点-逐标签提交盘点结果 - rqrq
export const pdaSubmitCount = data => createAPI(`/autoWareHourceHaian/haiAnPhysicalInventory/pda/submitCount`, 'post', data)
// 海安PDA手工盘点-调用托盘至盘点口(走海安新立库接口)- rqrq
export const scanAndCallPalletForPandian = data => createAPI(`/autoWareHourceHaian/haiAnPhysicalInventory/pda/callPalletForPandian`, 'post', data)

2
src/router/index.js

@ -163,6 +163,8 @@ const globalRoutes = [
{path: "/haianPalletManualMove",name: "haianPalletManualMove", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianPalletManualMove.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/haianWmsCancelReserve",name: "haianWmsCancelReserve", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianWmsCancelReserve.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
{path: "/haianCallOutForHetuo",name: "haianCallOutForHetuo", component: resolve => require(["@/views/modules/haianAutoWarehouse/haianCallOutForHetuo.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: true}},
// 海安立库手工盘点页面(固定工厂54)- rqrq
{path: "/haianManualCount54",name: "haianManualCount54", component: resolve => require(["@/views/modules/haianAutoWarehouse/manualCount54.vue"], resolve), meta: { transition: 'instant' ,preload: true,keepAlive: false}},
]

6
src/views/main.vue

@ -207,6 +207,12 @@
</div>
<div class="menu-text">取消预留</div>
</div>
<div class="menu-item" v-site-auth="'54'" @click="navigateWithWarehouseCheck('haianManualCount54')">
<div class="menu-icon purchase">
<van-icon name="shopping-cart-o" size="24" />
</div>
<div class="menu-text">立库手工盘点</div>
</div>
<!-- <div class="menu-item" v-site-auth="'54'" @click="navigateWithWarehouseCheck('haianCallOutForHetuo')">-->
<!-- <div class="menu-icon purchase">-->
<!-- <van-icon name="shopping-cart-o" size="24" />-->

52
src/views/modules/haianAutoWarehouse/haianCancelWcsPallet.vue

@ -56,8 +56,8 @@
</button>
</div>
<!-- 取消组盘按钮只有发送了组盘任务才显示- rqrq -->
<div class="button-row">
<!-- 取消组盘按钮已组盘且不在wcs_location/输送线禁操作状态时显示- rqrq -->
<div v-if="showCancelButton" class="button-row">
<button
class="action-btn primary"
@click="handleCancelWcsPallet"
@ -66,7 +66,7 @@
</button>
</div>
<!-- 移出全部物料按钮只有未发送组盘任务且未被调用且有明细才显示- rqrq -->
<!-- 移出全部物料按钮未组盘+未调用+有明细且不在wcs_location/输送线时显示- rqrq -->
<div v-if="showRemoveAllButton" class="button-row">
<button
class="action-btn warning"
@ -141,9 +141,13 @@ export default {
palletCode: '',
palletScanned: false,
palletInfo: {
locationCode: '',
wcsLocation: '',
area: '',
callingFlag: '',
canOperate: '',
isEmpty: ''
isEmpty: '',
hasSentWcsTask: ''
},
// - rqrq
@ -201,8 +205,10 @@ export default {
// isEmptyshowRemoveAllButton- rqrq
this.showRemoveAllButton = data.row.isEmpty === 'Y';
// hasSentWcsTask - rqrq
this.hasSentWcsTask = this.showCancelButton;
// hasSentWcsTask使 - rqrq
this.hasSentWcsTask = data.row.hasSentWcsTask
? data.row.hasSentWcsTask === 'Y'
: this.showCancelButton;
// - rqrq
this.loadPalletDetails();
@ -260,8 +266,29 @@ export default {
this.detailModalVisible = true;
},
// /wcs_location线 - rqrq
resolveManualOperationBlockedMessage() {
const wcsLocation = (this.palletInfo.wcsLocation || '').trim();
if (wcsLocation) {
return `当前栈板wcs_location有值(${wcsLocation}),不允许取消组盘或一键移出。`;
}
const locationCode = (this.palletInfo.locationCode || '').trim();
const isConveyor = locationCode.toUpperCase() === 'VIRTUAL_AS' || locationCode === '立库输送线';
if (isConveyor) {
return '当前栈板位于输送线,不允许取消组盘或一键移出。';
}
return '';
},
// - rqrq
handleCancelWcsPallet() {
const blockedMessage = this.resolveManualOperationBlockedMessage();
if (blockedMessage) {
this.$alert(blockedMessage, '提示', {
confirmButtonText: '确定'
});
return;
}
this.$confirm('确定要取消组盘吗?取消后需要重新组盘才能推送到WCS。', '确认操作', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -298,6 +325,13 @@ export default {
// - rqrq
handleRemoveAllMaterials() {
const blockedMessage = this.resolveManualOperationBlockedMessage();
if (blockedMessage) {
this.$alert(blockedMessage, '提示', {
confirmButtonText: '确定'
});
return;
}
this.$confirm('确定要移出栈板上的全部物料吗?此操作不可恢复!', '确认操作', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -337,9 +371,13 @@ export default {
this.palletCode = '';
this.palletScanned = false;
this.palletInfo = {
locationCode: '',
wcsLocation: '',
area: '',
callingFlag: '',
canOperate: '',
isEmpty: ''
isEmpty: '',
hasSentWcsTask: ''
};
this.hasSentWcsTask = false;
this.showCancelButton = false;

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

@ -773,7 +773,8 @@ export default {
partNo: original.partNo || '',
createDate: original.createDate,
createBy: original.createBy || '',
wcsFlag: original.wcsFlag || 1
// wcsFlag0|| 1 - rqrq
wcsFlag: original.wcsFlag === null || original.wcsFlag === undefined ? 0 : original.wcsFlag
}
}
this.$message.success('分拣扫进成功')
@ -813,7 +814,8 @@ export default {
partNo: original.partNo,
createDate: original.createDate,
createBy: original.createBy,
wcsFlag: original.wcsFlag
// 0线 - rqrq
wcsFlag: 0
}).then(({ data }) => {
if (data && data.code === 0) {
delete this.originalDetailCache[this.scanCode]

660
src/views/modules/haianAutoWarehouse/manualCount54.vue

@ -0,0 +1,660 @@
<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: 500px; overflow-y: auto;">
<div class="main-content form-section">
<!-- 第一行栈板扫描 - rqrq -->
<div class="input-group">
<label class="input-label">栈板编码</label>
<div style="display: flex; gap: 8px;">
<el-input
v-model="palletCode"
placeholder="请扫描栈板编码"
class="form-input"
style="flex: 1;"
clearable
inputmode="none"
autocomplete="off"
autocorrect="off"
spellcheck="false"
@keyup.enter.native="handlePalletScan"
ref="palletInput"
:disabled="palletScanned"
/>
</div>
</div>
<!-- 扫描栈板成功后显示的区域 - rqrq -->
<template v-if="palletScanned">
<!-- 扫描标签输入框 - rqrq -->
<div class="input-group">
<label class="input-label">扫描标签</label>
<el-input
v-model="labelCode"
placeholder="请扫描标签"
class="form-input"
clearable
inputmode="none"
autocomplete="off"
@keyup.enter.native="handleLabelScan"
ref="labelInput"
/>
</div>
<!-- 按钮区域 - rqrq -->
<div class="input-group" style="margin-top: 10px;">
<div style="display: flex; gap: 8px;">
<button
class="action-btn primary"
style="flex: 1;"
@click="handleQuickSubmit"
:disabled="submitLoading">
{{ submitLoading ? '提交中...' : '一键提交' }}
</button>
<button
class="action-btn warning"
style="flex: 1;"
@click="handleSubmitCount"
:disabled="submitLoading">
{{ submitLoading ? '提交中...' : '提交盘点' }}
</button>
</div>
</div>
<!-- 查看已扫描标签按钮 - rqrq -->
<div class="input-group" style="margin-top: 5px;">
<button
class="action-btn secondary"
style="width: 100%;"
@click="showScannedList">
查看已扫描({{ scannedLabels.length }})
</button>
</div>
</template>
</div>
<!-- 栈板盘点标签明细 - rqrq -->
<div v-if="palletScanned" class="rma-list">
<div class="list-title">
盘点标签明细 ({{ labelList.length }})
</div>
<div class="detail-table">
<div class="table-header">
<div class="col-label">标签号</div>
<div class="col-part">物料号</div>
<div class="col-status">状态</div>
</div>
<div class="table-body-scroll">
<div
v-for="(item, index) in labelList"
:key="index"
class="table-row"
:class="{'row-checked': item.countFlag === 'Y'}">
<div class="col-label">{{ item.unitId }}</div>
<div class="col-part">{{ item.partNo }}</div>
<div class="col-status" :style="{color: item.countFlag === 'Y' ? '#67C23A' : '#F56C6C'}">
{{ item.countFlagDesc }}
</div>
</div>
<div v-if="labelList.length === 0" class="empty-row">
暂无数据
</div>
</div>
</div>
</div>
</div>
<!-- 重新扫描按钮 - rqrq -->
<!-- <div v-if="palletScanned" class="footer-bar">-->
<!-- <button class="action-btn secondary" style="width: 100%;" @click="handleReset">-->
<!-- 重新扫描-->
<!-- </button>-->
<!-- </div>-->
</div>
<!-- 扫描标签弹框 - rqrq -->
<el-dialog
title="确认标签信息"
:visible.sync="labelDialogVisible"
width="90%"
:close-on-click-modal="false"
:show-close="true"
:modal="true"
:modal-append-to-body="true"
:append-to-body="true">
<div class="label-info">
<div class="info-row">
<span class="info-label">标签号</span>
<span class="info-value">{{ currentLabel.unitId }}</span>
</div>
<div class="info-row">
<span class="info-label">物料编码</span>
<span class="info-value">{{ currentLabel.partNo }}</span>
</div>
<div class="info-row">
<span class="info-label">批号</span>
<span class="info-value">{{ currentLabel.batchNo }}</span>
</div>
<div class="info-row">
<span class="info-label">数量</span>
<el-input
v-model="currentLabel.qty"
type="number"
style="width: 100%;">
</el-input>
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn primary" @click="confirmLabelScan"> </button>
<button class="action-btn secondary" style="margin-left: 10px;" @click="labelDialogVisible = false"> </button>
</div>
</el-dialog>
<!-- 已扫描标签列表弹框 - rqrq -->
<el-dialog
title="已扫描标签列表"
:visible.sync="scannedDialogVisible"
width="90%"
:close-on-click-modal="false"
:show-close="true"
:modal="true"
:modal-append-to-body="true"
:append-to-body="true">
<div class="scanned-list">
<div v-for="(item, index) in scannedLabels" :key="index" class="scanned-item">
<div class="scanned-info">
<div>标签{{ item.unitId }}</div>
<div>物料{{ item.partNo }}</div>
<div>数量{{ item.qty }}</div>
</div>
<button class="action-btn danger" @click="removeScannedLabel(index)">删除</button>
</div>
<div v-if="scannedLabels.length === 0" class="empty-list">
暂无扫描记录
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="action-btn secondary" @click="scannedDialogVisible = false"> </button>
</div>
</el-dialog>
</div>
</template>
<script>
import { pdaScanPallet, pdaScanLabel, pdaQuickSubmitCount, pdaSubmitCount } from '@/api/haianAutoWarehouse/manualCount'
export default {
name: 'manualCount54',
data() {
return {
// - rqrq
palletCode: '',
palletScanned: false,
countNo: '',
cleanPalletId: '',
// - rqrq
labelList: [],
// - rqrq
labelCode: '',
labelDialogVisible: false,
currentLabel: {
unitId: '',
partNo: '',
batchNo: '',
qty: 0
},
// - rqrq
scannedLabels: [],
scannedDialogVisible: false,
// - rqrq
submitLoading: false
}
},
mounted() {
this.$nextTick(() => {
this.$refs.palletInput.focus()
})
},
methods: {
// - rqrq
handleBack() {
this.$router.go(-1)
},
// - rqrq
handlePalletScan() {
if (!this.palletCode.trim()) {
this.$message.error('请输入栈板编码')
return
}
const params = {
site: this.$store.state.user.site,
palletId: this.palletCode
}
pdaScanPallet(params).then(({ data }) => {
if (data && data.code === 0) {
const result = data.data
this.cleanPalletId = result.cleanPalletId
this.countNo = result.countNo
this.labelList = result.labelList || []
this.palletCode = result.cleanPalletId //
this.palletScanned = true
this.scannedLabels = [] //
this.$message.success('栈板验证成功')
// - rqrq
this.$nextTick(() => {
this.$refs.labelInput.focus()
})
} else {
this.$message.error(data.msg || '扫描失败')
}
}).catch(() => {
this.$message.error('网络错误')
})
},
// - rqrq
handleLabelScan() {
if (!this.labelCode.trim()) {
return
}
const params = {
site: this.$store.state.user.site,
unitId: this.labelCode.trim()
}
pdaScanLabel(params).then(({ data }) => {
if (data && data.code === 0) {
const label = data.row
this.currentLabel = {
unitId: label.unitId,
partNo: label.partNo,
batchNo: label.batchNo,
qty: label.qty
}
this.labelDialogVisible = true
this.labelCode = '' //
} else {
this.$message.error(data.msg || '标签不存在')
this.labelCode = ''
this.$refs.labelInput.focus()
}
}).catch(() => {
this.$message.error('网络错误')
this.labelCode = ''
this.$refs.labelInput.focus()
})
},
// - rqrq
confirmLabelScan() {
// - rqrq
const existIndex = this.scannedLabels.findIndex(item => item.unitId === this.currentLabel.unitId)
if (existIndex >= 0) {
//
this.scannedLabels[existIndex].qty = this.currentLabel.qty
this.$message.success('标签数量已更新')
} else {
//
this.scannedLabels.push({
unitId: this.currentLabel.unitId,
partNo: this.currentLabel.partNo,
qty: this.currentLabel.qty
})
this.$message.success('标签已添加')
}
this.labelDialogVisible = false
// - rqrq
this.$nextTick(() => {
this.$refs.labelInput.focus()
})
},
// - rqrq
showScannedList() {
this.scannedDialogVisible = true
},
// - rqrq
removeScannedLabel(index) {
this.scannedLabels.splice(index, 1)
this.$message.success('已删除')
},
// OK- rqrq
handleQuickSubmit() {
this.$confirm('一键提交将默认所有标签盘点正常,确定要提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.submitLoading = true
const params = {
site: this.$store.state.user.site,
countNo: this.countNo,
palletId: this.cleanPalletId,
username: this.$store.state.user.name
}
pdaQuickSubmitCount(params).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('提交成功,生成盘点结果数:' + data.result)
this.handleReset()
} else {
this.$message.error(data.msg || '提交失败')
}
}).catch(() => {
this.$message.error('网络错误')
}).finally(() => {
this.submitLoading = false
})
}).catch(() => {})
},
// - rqrq
handleSubmitCount() {
if (this.scannedLabels.length === 0) {
this.$confirm('您没有扫描任何标签,将标记所有标签为盘亏,确定要提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doSubmitCount()
}).catch(() => {})
} else {
this.$confirm('确定要提交盘点结果吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info'
}).then(() => {
this.doSubmitCount()
}).catch(() => {})
}
},
// - rqrq
doSubmitCount() {
this.submitLoading = true
const params = {
site: this.$store.state.user.site,
countNo: this.countNo,
palletId: this.cleanPalletId,
scannedLabels: this.scannedLabels,
username: this.$store.state.user.name
}
pdaSubmitCount(params).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('提交成功,生成盘点结果数:' + data.result)
this.handleReset()
} else {
this.$message.error(data.msg || '提交失败')
}
}).catch(() => {
this.$message.error('网络错误')
}).finally(() => {
this.submitLoading = false
})
},
// - rqrq
handleReset() {
this.palletCode = ''
this.palletScanned = false
this.countNo = ''
this.cleanPalletId = ''
this.labelList = []
this.labelCode = ''
this.scannedLabels = []
this.$nextTick(() => {
this.$refs.palletInput.focus()
})
}
}
}
</script>
<style scoped>
/* 表格样式 - 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;
}
.table-row.row-checked {
background-color: #e8f5e9;
}
.table-body-scroll {
max-height: 200px;
overflow-y: auto;
}
.col-label {
flex: 2;
text-align: center;
word-break: break-all;
}
.col-part {
flex: 1.5;
text-align: center;
word-break: break-all;
}
.col-status {
flex: 0.8;
text-align: center;
}
/* 空数据提示 - rqrq */
.empty-row {
text-align: center;
color: #999;
padding: 20px;
}
/* 按钮样式覆盖 - 使用绿色主题 - rqrq */
.action-btn {
padding: 12px 16px;
border: 1px solid #17B3A3;
background: white;
color: #17B3A3;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
display: inline-block;
min-width: 60px;
text-align: center;
}
.action-btn:hover {
background: #17B3A3;
color: white;
}
.action-btn:active {
transform: scale(0.98);
}
.action-btn.primary {
background-color: #17B3A3;
border-color: #17B3A3;
color: white;
}
.action-btn.primary:hover {
background-color: #15a093;
border-color: #15a093;
}
.action-btn.warning {
background-color: #E6A23C;
border-color: #E6A23C;
color: white;
}
.action-btn.warning:hover {
background-color: #f0b757;
border-color: #f0b757;
}
.action-btn.secondary {
background-color: #f5f5f5;
border-color: #dcdfe6;
color: #606266;
}
.action-btn.secondary:hover {
background-color: #e4e7ed;
border-color: #d3d4d6;
}
.action-btn.danger {
background-color: #F56C6C;
border-color: #F56C6C;
color: white;
padding: 8px 12px;
font-size: 12px;
}
.action-btn.danger:hover {
background-color: #f78989;
border-color: #f78989;
}
.action-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
background-color: #ccc !important;
border-color: #ccc !important;
}
/* 弹窗底部按钮区域 - rqrq */
.dialog-footer {
text-align: center;
padding: 10px 0;
}
/* 底部操作栏 - rqrq */
.footer-bar {
padding: 16px;
background-color: white;
position: fixed;
bottom: 0;
left: 0;
right: 0;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
}
/* 列表标题使用绿色 - rqrq */
.list-title {
font-size: 16px;
font-weight: bold;
color: #17b3a3;
margin: 12px 0 8px 0;
}
/* 标签信息弹框样式 - rqrq */
.label-info {
padding: 10px;
}
.label-info .info-row {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.label-info .info-label {
width: 80px;
color: #606266;
font-size: 14px;
}
.label-info .info-value {
flex: 1;
color: #303133;
font-size: 14px;
}
/* 已扫描列表样式 - rqrq */
.scanned-list {
max-height: 300px;
overflow-y: auto;
}
.scanned-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #EBEEF5;
}
.scanned-info {
font-size: 12px;
color: #606266;
}
.scanned-info div {
margin-bottom: 4px;
}
.empty-list {
padding: 30px;
text-align: center;
color: #909399;
}
</style>
Loading…
Cancel
Save