You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

404 lines
9.8 KiB

<template>
<div>
<div class="pda-container">
<div class="header-bar">
<div class="header-left" :class="{ 'header-action-disabled': pageBusy }" @click="handleBack">
<i class="el-icon-arrow-left"></i>
<!-- WMS标签状态统一展示为预定,reserve字段和Y/N判断保持原有业务含义 - rqrq -->
<span>取消预定</span>
</div>
<div class="header-right" :class="{ 'header-action-disabled': pageBusy }" @click="goHome">
首页
</div>
</div>
<div class="table-body" style="max-height: 500px; overflow-y: auto;">
<div class="main-content form-section">
<div class="input-group">
<label class="input-label">标签编码</label>
<el-input
v-model="labelCode"
placeholder="请扫描标签编码"
class="form-input"
clearable
inputmode="none"
autocomplete="off"
autocorrect="off"
spellcheck="false"
@keyup.enter.native="handleLabelScan"
ref="labelInput"
/>
</div>
<div v-if="labelInfo" class="info-section">
<div class="info-title">
<i class="el-icon-document"></i>
<span>标签信息</span>
</div>
<div class="info-row">
<span class="info-label">标签编码:</span>
<span class="info-value">{{ labelInfo.unitId || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">工厂编码:</span>
<span class="info-value">{{ labelInfo.site || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">物料编码:</span>
<span class="info-value">{{ labelInfo.partNo || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">数量:</span>
<span class="info-value">{{ labelInfo.qty || '0' }}</span>
</div>
<div class="info-row">
<span class="info-label">批次号:</span>
<span class="info-value">{{ labelInfo.batchNo || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">仓库:</span>
<span class="info-value">{{ labelInfo.warehouseId || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">库位:</span>
<span class="info-value">{{ labelInfo.locationId || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">WDR:</span>
<span class="info-value">{{ labelInfo.wdr || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">是否被WMS预定:</span>
<span class="info-value" :style="{ color: labelInfo.reserveFlag === 'Y' ? '#F56C6C' : '#67C23A' }">
{{ labelInfo.reserveFlag === 'Y' ? '是' : '否' }}
</span>
</div>
<div class="info-row" v-if="labelInfo.reserveOrderRef1">
<span class="info-label">预定申请单号:</span>
<span class="info-value">{{ labelInfo.reserveOrderRef1 || '-' }}</span>
</div>
<div class="info-row" v-if="labelInfo.reserveOrderRef3">
<span class="info-label">预定订单号:</span>
<span class="info-value">{{ labelInfo.reserveOrderRef3 || '-' }}</span>
</div>
</div>
<div v-if="labelInfo" class="bottom-actions">
<button class="action-btn secondary" @click="clearData" :disabled="pageBusy">清空</button>
<button
class="action-btn primary"
@click="handleCancelReserve"
:disabled="cancelReserveLoading || labelInfo.reserveFlag !== 'Y'"
>
{{ cancelReserveLoading ? '取消中...' : '取消预定' }}
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { queryLabelInfo, cancelReserve } from '@/api/haianAutoWarehouse/wmsCancelReserve'
export default {
name: 'HaianWmsCancelReserve',
data() {
return {
site: this.$store.state.user.site,
labelCode: '',
labelInfo: null,
loading: false,
cancelReserveLoading: false
}
},
computed: {
pageBusy() {
return this.loading || this.cancelReserveLoading
}
},
methods: {
handleBack() {
if (this.pageBusy) {
return
}
this.resetPage(false)
this.$router.back()
},
goHome() {
if (this.pageBusy) {
return
}
this.resetPage(false)
this.$router.push({ path: '/' })
},
// 统一状态清理:避免页面缓存导致上一单标签信息残留 - rqrq
resetPage(needFocus = true) {
this.site = this.$store.state.user.site
this.labelCode = ''
this.labelInfo = null
this.loading = false
this.cancelReserveLoading = false
if (needFocus) {
this.focusLabelInput()
}
},
handleLabelScan() {
if (!this.labelCode || !this.labelCode.trim()) {
this.$message.error('请扫描有效的标签编码')
return
}
this.loading = true
queryLabelInfo({
site: this.site,
serialNo: this.labelCode.trim()
}).then(({ data }) => {
if (data && data.code === 0) {
this.labelInfo = data.data
this.$message.success('查询成功')
} else {
this.$message.error((data && data.msg) || '标签不存在')
this.labelCode = ''
this.labelInfo = null
this.focusLabelInput()
}
}).catch(() => {
this.$message.error('查询异常')
this.labelCode = ''
this.labelInfo = null
this.focusLabelInput()
}).finally(() => {
this.loading = false
})
},
handleCancelReserve() {
if (!this.labelInfo || this.labelInfo.reserveFlag !== 'Y') {
this.$message.warning('当前标签未被预定')
return
}
this.$confirm('确定要取消该标签的WMS预定吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doCancelReserve()
}).catch(() => {
// 用户取消 - rqrq
})
},
doCancelReserve() {
this.cancelReserveLoading = true
cancelReserve({
site: this.site,
serialNo: this.labelInfo.unitId
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('取消预定成功')
this.clearData()
} else {
this.$message.error((data && data.msg) || '取消预定失败')
}
}).catch(() => {
this.$message.error('取消预定异常')
}).finally(() => {
this.cancelReserveLoading = false
})
},
clearData() {
this.labelCode = ''
this.labelInfo = null
this.focusLabelInput()
},
focusLabelInput() {
this.$nextTick(() => {
if (this.$refs.labelInput) {
this.$refs.labelInput.focus()
}
})
}
},
mounted() {
this.resetPage(true)
},
activated() {
this.resetPage(true)
},
beforeRouteLeave(to, from, next) {
this.resetPage(false)
next()
}
}
</script>
<style scoped>
.header-action-disabled {
opacity: 0.5;
pointer-events: none;
}
.pda-container {
width: 100vw;
height: 120vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
font-family: 'Arial', sans-serif;
}
.header-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background: #17B3A3;
color: white;
height: 40px;
min-height: 40px;
max-height: 40px;
}
.header-left {
display: flex;
align-items: center;
cursor: pointer;
}
.header-left i {
margin-right: 8px;
font-size: 18px;
}
.header-left span {
font-size: 16px;
font-weight: 500;
}
.header-right {
cursor: pointer;
font-size: 14px;
padding: 4px 8px;
border-radius: 4px;
}
.table-body {
flex: 1;
overflow-y: auto;
}
.main-content {
padding: 16px;
}
.input-label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 500;
color: #333;
}
.form-input {
width: 100%;
height: 44px;
}
.info-section {
background: white;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.info-title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: bold;
color: #17B3A3;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #17B3A3;
}
.info-title i {
margin-right: 8px;
font-size: 18px;
}
.info-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
}
.info-row:last-child {
border-bottom: none;
}
.info-label {
font-size: 14px;
color: #666;
min-width: 90px;
flex-shrink: 0;
}
.info-value {
font-size: 14px;
font-weight: 500;
color: #333;
flex: 1;
text-align: right;
word-break: break-all;
}
.bottom-actions {
display: flex;
gap: 12px;
padding-top: 16px;
}
.action-btn {
flex: 1;
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
min-height: 44px;
}
.action-btn.primary {
background: #17B3A3;
color: white;
}
.action-btn.primary:hover {
background: #15a394;
}
.action-btn.primary:disabled {
background: #ccc;
cursor: not-allowed;
opacity: 0.6;
}
.action-btn.secondary {
background: #f5f5f5;
color: #333;
border: 1px solid #ddd;
}
.action-btn.secondary:hover {
background: #e8e8e8;
}
.action-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
</style>