Browse Source

标签纠正

master
常熟吴彦祖 3 weeks ago
parent
commit
9271d8b9d6
  1. 653
      src/views/modules/inventory/label-calibration.vue

653
src/views/modules/inventory/label-calibration.vue

@ -0,0 +1,653 @@
<template>
<div>
<div class="pda-container">
<!-- 头部栏 -->
<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: calc(100vh - 60px); overflow-y: auto;">
<div class="main-content form-section">
<!-- 标签扫描输入框 -->
<div class="input-group">
<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>
<!-- WMS标签信息显示 (扫描后显示) -->
<div v-if="labelInfo" class="info-section">
<div class="info-title">
<i class="el-icon-document"></i>
<span>WMS标签信息</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.partNo || '-' }}</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.qty || '0' }}</span>
</div>
<div class="info-row">
<span class="info-label">库位:</span>
<span class="info-value highlight">{{ labelInfo.locationId || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">WDR:</span>
<span class="info-value highlight">{{ labelInfo.wdr || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">失效日期:</span>
<span class="info-value highlight">{{ formatDate(labelInfo.expiredDate) }}</span>
</div>
<div class="info-row">
<span class="info-label">版本号:</span>
<span class="info-value highlight">{{ labelInfo.engChgLevel || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">可用控制:</span>
<span class="info-value highlight">{{ labelInfo.availabilityControlId || '-' }}</span>
</div>
</div>
<!-- IFS库存列表 (扫描后显示) -->
<div v-if="labelInfo && matchedIfsList && matchedIfsList.length > 0" class="ifs-section">
<div class="info-title">
<i class="el-icon-s-data"></i>
<span>IFS库存列表同物料+同批次</span>
</div>
<div class="ifs-list">
<div
v-for="(item, index) in matchedIfsList"
:key="index"
class="ifs-item"
:class="{ 'selected': selectedIndex === index }"
@click="selectIfsItem(index)"
>
<div class="ifs-item-header">
<span class="ifs-index">#{{ index + 1 }}</span>
<span v-if="selectedIndex === index" class="ifs-selected-tag">已选择</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">库位:</span>
<span class="ifs-value">{{ item.LocationNo || item.locationNo || '-' }}</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">WDR:</span>
<span class="ifs-value">{{ item.WaivDevRejNo || item.waivDevRejNo || '-' }}</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">失效日期:</span>
<span class="ifs-value">{{ item.ExpirationDate || item.expirationDate || '-' }}</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">版本号:</span>
<span class="ifs-value">{{ item.EngChgLevel || item.engChgLevel || '-' }}</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">可用控制:</span>
<span class="ifs-value">{{ item.AvailabilityControlId || item.availabilityControlId || '-' }}</span>
</div>
<div class="ifs-item-row">
<span class="ifs-label">在库数量:</span>
<span class="ifs-value qty">{{ item.QtyOnhand || item.qtyOnhand || '0' }}</span>
</div>
</div>
</div>
</div>
<!-- 无匹配数据提示 -->
<div v-if="labelInfo && (!matchedIfsList || matchedIfsList.length === 0)" class="no-data-section">
<i class="el-icon-warning-outline"></i>
<span>IFS中未找到匹配的库存记录</span>
</div>
<!-- 底部操作按钮 -->
<div v-if="labelInfo" class="bottom-actions">
<button
class="action-btn primary"
@click="handleCalibrate"
:disabled="calibrateLoading || selectedIndex === null"
>
{{ calibrateLoading ? '纠正中...' : '纠正' }}
</button>
<button
class="action-btn secondary"
@click="clearData"
:disabled="calibrateLoading"
>
清空
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { queryLabelCalibration, calibrateLabel } from '@/api/inventory/label'
export default {
name: 'LabelCalibration',
data() {
return {
site: localStorage.getItem('site'),
labelCode: '',
labelInfo: null,
matchedIfsList: [],
selectedIndex: null,
loading: false,
calibrateLoading: false
}
},
methods: {
/**
* 返回上一页 - rqrq
*/
handleBack() {
this.$router.back()
},
/**
* 处理标签扫描 - rqrq
*/
handleLabelScan() {
if (!this.labelCode.trim()) {
this.$message.error('请扫描有效的标签编码')
return
}
this.loading = true
this.labelInfo = null
this.matchedIfsList = []
this.selectedIndex = null
queryLabelCalibration({
site: this.site,
unitId: this.labelCode.trim()
}).then(({ data }) => {
this.loading = false
if (data && data.code === 0) {
this.labelInfo = data.row
this.matchedIfsList = data.row.matchedIfsList || []
this.$message.success('查询成功')
} else {
this.$message.error(data.msg || '查询失败')
this.labelCode = ''
this.focusLabelInput()
}
}).catch(error => {
this.loading = false
console.error('查询标签失败:', error)
this.$message.error('查询异常')
this.labelCode = ''
this.focusLabelInput()
})
},
/**
* 选择IFS库存项 - rqrq
*/
selectIfsItem(index) {
if (this.selectedIndex === index) {
this.selectedIndex = null
} else {
this.selectedIndex = index
}
},
/**
* 执行标签校准纠正 - rqrq
*/
handleCalibrate() {
if (this.selectedIndex === null) {
this.$message.warning('请先选择要纠正成的IFS库存')
return
}
const selectedItem = this.matchedIfsList[this.selectedIndex]
this.$confirm(
`确定要将标签校准为以下信息吗?<br/><br/>` +
`库位: ${selectedItem.LocationNo || selectedItem.locationNo || '-'}<br/>` +
`WDR: ${selectedItem.WaivDevRejNo || selectedItem.waivDevRejNo || '-'}<br/>` +
`失效日期: ${selectedItem.ExpirationDate || selectedItem.expirationDate || '-'}<br/>` +
`版本号: ${selectedItem.EngChgLevel || selectedItem.engChgLevel || '-'}`,
'确认纠正',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}
).then(() => {
this.doCalibrate(selectedItem)
}).catch(() => {
//
})
},
/**
* 执行纠正操作 - rqrq
*/
doCalibrate(selectedItem) {
this.calibrateLoading = true
calibrateLabel({
site: this.site,
unitId: this.labelInfo.unitId,
username: localStorage.getItem('userName'),
selectedLocationNo: selectedItem.LocationNo || selectedItem.locationNo,
selectedWaivDevRejNo: selectedItem.WaivDevRejNo || selectedItem.waivDevRejNo,
selectedExpirationDate: selectedItem.ExpirationDate || selectedItem.expirationDate,
selectedEngChgLevel: selectedItem.EngChgLevel || selectedItem.engChgLevel,
selectedAvailabilityControlId: selectedItem.AvailabilityControlId || selectedItem.availabilityControlId
}).then(({ data }) => {
this.calibrateLoading = false
if (data && data.code === 0) {
this.$message.success('标签校准成功!')
//
this.labelInfo = data.row
this.selectedIndex = null
// IFS
this.handleLabelScan()
} else {
this.$message.error(data.msg || '校准失败')
}
}).catch(error => {
this.calibrateLoading = false
console.error('标签校准失败:', error)
this.$message.error('校准异常: ' + (error.message || error))
})
},
/**
* 清空数据 - rqrq
*/
clearData() {
this.labelCode = ''
this.labelInfo = null
this.matchedIfsList = []
this.selectedIndex = null
this.focusLabelInput()
},
/**
* 聚焦标签输入框 - rqrq
*/
focusLabelInput() {
this.$nextTick(() => {
if (this.$refs.labelInput) {
this.$refs.labelInput.focus()
}
})
},
/**
* 格式化日期 - rqrq
*/
formatDate(date) {
if (!date) return '-'
const d = new Date(date)
const year = d.getFullYear()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
},
mounted() {
// - rqrq
this.focusLabelInput()
}
}
</script>
<style scoped>
.input-group {
margin-bottom: 12px !important;
}
/* PDA容器样式 - rqrq */
.pda-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
font-family: 'Arial', sans-serif;
}
/* 头部栏样式 - rqrq */
.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;
}
/* 主要内容区 - rqrq */
.table-body {
flex: 1;
overflow-y: auto;
}
.main-content {
padding: 16px;
}
/* 输入框样式 - rqrq */
.form-input {
width: 100%;
height: 44px;
}
/* 信息展示区 - rqrq */
.info-section {
background: white;
border-radius: 8px;
padding: 16px;
margin-bottom: 12px;
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: 12px;
padding-bottom: 8px;
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: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.info-row:last-child {
border-bottom: none;
}
.info-label {
font-size: 14px;
color: #666;
min-width: 80px;
flex-shrink: 0;
}
.info-value {
font-size: 14px;
font-weight: 500;
color: #333;
flex: 1;
text-align: right;
word-break: break-all;
}
.info-value.highlight {
color: #E6A23C;
font-weight: bold;
}
/* IFS库存列表区 - rqrq */
.ifs-section {
background: white;
border-radius: 8px;
padding: 16px;
margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.ifs-list {
max-height: 300px;
overflow-y: auto;
}
.ifs-item {
background: #fafafa;
border: 2px solid #e0e0e0;
border-radius: 8px;
padding: 12px;
margin-bottom: 10px;
cursor: pointer;
transition: all 0.2s;
}
.ifs-item:hover {
border-color: #17B3A3;
background: #f0faf9;
}
.ifs-item.selected {
border-color: #17B3A3;
background: #e6f7f5;
box-shadow: 0 2px 8px rgba(23, 179, 163, 0.3);
}
.ifs-item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px dashed #ddd;
}
.ifs-index {
font-size: 14px;
font-weight: bold;
color: #666;
}
.ifs-selected-tag {
background: #17B3A3;
color: white;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
}
.ifs-item-row {
display: flex;
justify-content: space-between;
padding: 4px 0;
}
.ifs-label {
font-size: 13px;
color: #888;
}
.ifs-value {
font-size: 13px;
color: #333;
font-weight: 500;
}
.ifs-value.qty {
color: #67C23A;
font-weight: bold;
}
/* 无数据提示 - rqrq */
.no-data-section {
background: #fff8e6;
border: 1px solid #ffc107;
border-radius: 8px;
padding: 20px;
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: center;
color: #856404;
}
.no-data-section i {
font-size: 20px;
margin-right: 8px;
}
/* 底部按钮区 - rqrq */
.bottom-actions {
display: flex;
gap: 12px;
padding-top: 16px;
}
.action-btn {
flex: 1;
padding: 14px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
min-height: 48px;
}
.action-btn.primary {
background: #17B3A3;
color: white;
}
.action-btn.primary:hover:not(:disabled) {
background: #15a394;
}
.action-btn.primary:disabled {
background: #ccc;
cursor: not-allowed;
}
.action-btn.secondary {
background: #f5f5f5;
color: #333;
border: 1px solid #ddd;
}
.action-btn.secondary:hover:not(:disabled) {
background: #e8e8e8;
}
.action-btn.secondary:disabled {
background: #f0f0f0;
color: #999;
cursor: not-allowed;
}
/* 响应式设计 - rqrq */
@media screen and (max-width: 480px) {
.header-bar {
padding: 8px 12px;
}
.main-content {
padding: 12px;
}
.info-section, .ifs-section {
padding: 12px;
}
.info-label, .ifs-label {
font-size: 12px;
}
.info-value, .ifs-value {
font-size: 12px;
}
.action-btn {
padding: 12px 16px;
font-size: 14px;
}
}
</style>
Loading…
Cancel
Save