|
|
|
@ -31,11 +31,11 @@ |
|
|
|
<div class="card-details"> |
|
|
|
<div class="detail-item"> |
|
|
|
<div class="detail-label">标签张数</div> |
|
|
|
<div class="detail-value qualified">{{ materialInfo.labelCount }}/{{ materialInfo.totalLabels }}</div> |
|
|
|
<div class="detail-value qualified">{{ materialInfo.labelinCount }}/{{ materialInfo.totalLabels }}</div> |
|
|
|
</div> |
|
|
|
<div class="detail-item"> |
|
|
|
<div class="detail-label">物料总数</div> |
|
|
|
<div class="detail-value qualified">{{ materialInfo.qualifiedQty }}/{{ materialInfo.totalQty }}</div> |
|
|
|
<div class="detail-value qualified">{{ materialInfo.totalinLabels }}/{{ materialInfo.labelCount }}</div> |
|
|
|
</div> |
|
|
|
<div class="detail-item"> |
|
|
|
<div class="detail-label">批次号</div> |
|
|
|
@ -50,8 +50,13 @@ |
|
|
|
|
|
|
|
<!-- 入库信息确认标题 --> |
|
|
|
<div class="section-title"> |
|
|
|
<i class="el-icon-circle-check"></i> |
|
|
|
<span>入库信息确认</span> |
|
|
|
<div class="title-left"> |
|
|
|
<i class="el-icon-circle-check"></i> |
|
|
|
<span>入库信息确认</span> |
|
|
|
</div> |
|
|
|
<div class="title-right"> |
|
|
|
<span class="material-list-link" @click="showMaterialListDialog">物料清单</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 标签列表 --> |
|
|
|
@ -129,11 +134,64 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 物料清单弹窗 --> |
|
|
|
<div v-if="showMaterialDialog" class="material-overlay"> |
|
|
|
<div class="material-modal"> |
|
|
|
<div class="modal-header"> |
|
|
|
<span class="modal-title">物料清单</span> |
|
|
|
<i class="el-icon-close close-btn" @click="closeMaterialDialog"></i> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="modal-body"> |
|
|
|
<!-- 加载状态 --> |
|
|
|
<div v-if="materialListLoading" class="loading-container"> |
|
|
|
<i class="el-icon-loading"></i> |
|
|
|
<span>加载中...</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 物料表格 --> |
|
|
|
<div v-else-if="materialList.length > 0" class="material-table"> |
|
|
|
<div class="table-header"> |
|
|
|
<div class="col-no">NO.</div> |
|
|
|
<!-- <div class="col-label-code">标签条码</div>--> |
|
|
|
<div class="col-material-code">物料编码</div> |
|
|
|
<div class="col-required-qty">需求数量</div> |
|
|
|
<div class="col-inbound-qty">已入库数</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="table-body"> |
|
|
|
<div |
|
|
|
v-for="(item, index) in materialList" |
|
|
|
:key="index" |
|
|
|
class="table-row" |
|
|
|
> |
|
|
|
<div class="col-no">{{ index + 1 }}</div> |
|
|
|
<!-- <div class="col-label-code">{{ item.labelCode || item.rollNo }}</div>--> |
|
|
|
<div class="col-material-code">{{ item.materialCode || item.partNo }}</div> |
|
|
|
<div class="col-required-qty">{{ item.labelCount || 0 }}</div> |
|
|
|
<div class="col-inbound-qty">{{ item.totalinLabels || 0 }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 空数据状态 --> |
|
|
|
<div v-else class="empty-material"> |
|
|
|
<i class="el-icon-document"></i> |
|
|
|
<p>暂无物料数据</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="modal-footer"> |
|
|
|
<button class="btn-close" @click="closeMaterialDialog">关闭</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel } from "@/api/inbound.js"; |
|
|
|
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel, getMaterialList } from "@/api/inbound.js"; |
|
|
|
import { getCurrentWarehouse } from '@/utils' |
|
|
|
import moment from 'moment'; |
|
|
|
export default { |
|
|
|
@ -145,7 +203,10 @@ export default { |
|
|
|
inboundNo: '', |
|
|
|
partNo: '', |
|
|
|
showLocationDialog: false, |
|
|
|
locationCode: '' |
|
|
|
locationCode: '', |
|
|
|
showMaterialDialog: false, |
|
|
|
materialList: [], |
|
|
|
materialListLoading: false |
|
|
|
}; |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
@ -309,11 +370,53 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 显示物料清单弹窗 |
|
|
|
showMaterialListDialog() { |
|
|
|
this.showMaterialDialog = true; |
|
|
|
this.loadMaterialList(); |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载物料清单 |
|
|
|
loadMaterialList() { |
|
|
|
if (!this.materialInfo.site || !this.materialInfo.buNo || !this.inboundNo) { |
|
|
|
this.$message.error('缺少必要参数,无法获取物料清单'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.materialListLoading = true; |
|
|
|
const params = { |
|
|
|
site: this.materialInfo.site, |
|
|
|
buNo: this.materialInfo.buNo, |
|
|
|
inboundNo: this.inboundNo |
|
|
|
}; |
|
|
|
|
|
|
|
getMaterialList(params).then(({ data }) => { |
|
|
|
this.materialListLoading = false; |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.materialList = data.data || []; |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '获取物料清单失败'); |
|
|
|
this.materialList = []; |
|
|
|
} |
|
|
|
}).catch(error => { |
|
|
|
this.materialListLoading = false; |
|
|
|
console.error('获取物料清单失败:', error); |
|
|
|
this.$message.error('获取物料清单失败'); |
|
|
|
this.materialList = []; |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 关闭物料清单弹窗 |
|
|
|
closeMaterialDialog() { |
|
|
|
this.showMaterialDialog = false; |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载入库单详情 |
|
|
|
loadInboundDetails() { |
|
|
|
const params = { |
|
|
|
inboundNo: this.inboundNo, |
|
|
|
partNo: this.partNo, |
|
|
|
buNo: this.buNo, |
|
|
|
warehouseId: getCurrentWarehouse(), |
|
|
|
site:localStorage.getItem('site'), |
|
|
|
}; |
|
|
|
@ -335,7 +438,7 @@ export default { |
|
|
|
// 获取路由参数 |
|
|
|
this.inboundNo = this.$route.params.inboundNo; |
|
|
|
this.partNo = this.$route.params.partNo; |
|
|
|
|
|
|
|
this.buNo = this.$route.params.buNo; |
|
|
|
if (!this.inboundNo || !this.partNo) { |
|
|
|
this.$message.error('参数错误'); |
|
|
|
this.$router.back(); |
|
|
|
@ -372,8 +475,8 @@ export default { |
|
|
|
padding: 8px 16px; |
|
|
|
background: #17B3A3; |
|
|
|
color: white; |
|
|
|
height: 50px; |
|
|
|
min-height: 50px; |
|
|
|
height: 40px; |
|
|
|
min-height: 40px; |
|
|
|
} |
|
|
|
|
|
|
|
.header-left { |
|
|
|
@ -494,14 +597,15 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
.detail-value.qualified { |
|
|
|
color: #00C853; |
|
|
|
font-weight: 600; |
|
|
|
color: #17B3A3; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
|
|
|
|
/* 区域标题 */ |
|
|
|
.section-title { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: space-between; |
|
|
|
padding: 12px 16px; |
|
|
|
background: white; |
|
|
|
margin: 0 16px; |
|
|
|
@ -510,16 +614,39 @@ export default { |
|
|
|
border-bottom: 2px solid #17B3A3; |
|
|
|
} |
|
|
|
|
|
|
|
.section-title i { |
|
|
|
.title-left { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.title-left i { |
|
|
|
color: #17B3A3; |
|
|
|
font-size: 16px; |
|
|
|
margin-right: 8px; |
|
|
|
} |
|
|
|
|
|
|
|
.section-title span { |
|
|
|
.title-left span { |
|
|
|
color: #17B3A3; |
|
|
|
font-size: 14px; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
|
|
|
|
.title-right { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.material-list-link { |
|
|
|
color: #17B3A3; |
|
|
|
font-size: 14px; |
|
|
|
font-weight: 500; |
|
|
|
cursor: pointer; |
|
|
|
text-decoration: underline; |
|
|
|
transition: color 0.2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.material-list-link:hover { |
|
|
|
color: #0d8f7f; |
|
|
|
} |
|
|
|
|
|
|
|
/* 标签列表 */ |
|
|
|
@ -553,7 +680,7 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
.col-no { |
|
|
|
width: 40px; |
|
|
|
width: 20px; |
|
|
|
text-align: center; |
|
|
|
} |
|
|
|
|
|
|
|
@ -825,4 +952,275 @@ export default { |
|
|
|
background: #c0c4cc; |
|
|
|
cursor: not-allowed; |
|
|
|
} |
|
|
|
|
|
|
|
/* 物料清单弹窗样式 */ |
|
|
|
.material-overlay { |
|
|
|
position: fixed; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
background: rgba(0, 0, 0, 0.5); |
|
|
|
z-index: 9999; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 20px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-modal { |
|
|
|
background: white; |
|
|
|
border-radius: 12px; |
|
|
|
width: 100%; |
|
|
|
max-width: 800px; |
|
|
|
max-height: 80vh; |
|
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); |
|
|
|
overflow: hidden; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
} |
|
|
|
|
|
|
|
.material-modal .modal-header { |
|
|
|
background: #17B3A3; |
|
|
|
color: white; |
|
|
|
padding: 5px 16px; |
|
|
|
display: flex; |
|
|
|
justify-content: space-between; |
|
|
|
align-items: center; |
|
|
|
min-height: 28px; |
|
|
|
} |
|
|
|
|
|
|
|
.close-btn { |
|
|
|
font-size: 16px; |
|
|
|
cursor: pointer; |
|
|
|
color: white; |
|
|
|
transition: color 0.2s ease; |
|
|
|
padding: 4px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
} |
|
|
|
|
|
|
|
.close-btn:hover { |
|
|
|
color: #e0e0e0; |
|
|
|
} |
|
|
|
|
|
|
|
.material-modal .modal-title { |
|
|
|
font-size: 16px; |
|
|
|
font-weight: 500; |
|
|
|
margin: 0; |
|
|
|
line-height: 1.2; |
|
|
|
} |
|
|
|
|
|
|
|
.material-modal .modal-body { |
|
|
|
flex: 1; |
|
|
|
overflow: auto; |
|
|
|
padding: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table { |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.table-header { |
|
|
|
display: flex; |
|
|
|
background: #f8f9fa; |
|
|
|
padding: 10px 6px; |
|
|
|
border-bottom: 2px solid #17B3A3; |
|
|
|
font-size: 12px; |
|
|
|
color: #333; |
|
|
|
font-weight: 600; |
|
|
|
position: sticky; |
|
|
|
top: 0; |
|
|
|
z-index: 1; |
|
|
|
} |
|
|
|
|
|
|
|
.table-body { |
|
|
|
max-height: 400px; |
|
|
|
overflow-y: auto; |
|
|
|
} |
|
|
|
|
|
|
|
.table-row { |
|
|
|
display: flex; |
|
|
|
padding: 10px 6px; |
|
|
|
border-bottom: 1px solid #f0f0f0; |
|
|
|
font-size: 12px; |
|
|
|
color: #333; |
|
|
|
transition: background-color 0.2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.table-row:hover { |
|
|
|
background-color: #f8f9fa; |
|
|
|
} |
|
|
|
|
|
|
|
.table-row:last-child { |
|
|
|
border-bottom: none; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-no { |
|
|
|
width: 25px; |
|
|
|
text-align: center; |
|
|
|
flex-shrink: 0; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-label-code { |
|
|
|
flex: 1.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 100px; |
|
|
|
font-size: 12px; |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-material-code { |
|
|
|
flex: 1.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 100px; |
|
|
|
font-size: 12px; |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-required-qty { |
|
|
|
flex: 0.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 65px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-inbound-qty { |
|
|
|
flex: 0.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 65px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-modal .modal-footer { |
|
|
|
padding: 15px 20px; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
border-top: 1px solid #f0f0f0; |
|
|
|
} |
|
|
|
|
|
|
|
.btn-close { |
|
|
|
padding: 10px 20px; |
|
|
|
border-radius: 6px; |
|
|
|
font-size: 14px; |
|
|
|
cursor: pointer; |
|
|
|
transition: all 0.2s; |
|
|
|
border: 1px solid #17B3A3; |
|
|
|
background: white; |
|
|
|
color: #17B3A3; |
|
|
|
} |
|
|
|
|
|
|
|
.btn-close:hover { |
|
|
|
background: #17B3A3; |
|
|
|
color: white; |
|
|
|
} |
|
|
|
|
|
|
|
/* 加载状态样式 */ |
|
|
|
.loading-container { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 60px 20px; |
|
|
|
color: #666; |
|
|
|
} |
|
|
|
|
|
|
|
.loading-container i { |
|
|
|
font-size: 24px; |
|
|
|
margin-bottom: 12px; |
|
|
|
color: #17B3A3; |
|
|
|
} |
|
|
|
|
|
|
|
.loading-container span { |
|
|
|
font-size: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 空数据状态样式 */ |
|
|
|
.empty-material { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 60px 20px; |
|
|
|
color: #999; |
|
|
|
} |
|
|
|
|
|
|
|
.empty-material i { |
|
|
|
font-size: 48px; |
|
|
|
margin-bottom: 16px; |
|
|
|
color: #ddd; |
|
|
|
} |
|
|
|
|
|
|
|
.empty-material p { |
|
|
|
margin: 0; |
|
|
|
font-size: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式设计 - 物料清单弹窗 */ |
|
|
|
@media (max-width: 768px) { |
|
|
|
.material-modal { |
|
|
|
max-width: 98vw; |
|
|
|
max-height: 85vh; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-no { |
|
|
|
width: 25px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-label-code, |
|
|
|
.material-table .col-material-code { |
|
|
|
flex: 1.5; |
|
|
|
min-width: 85px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-required-qty, |
|
|
|
.material-table .col-inbound-qty { |
|
|
|
flex: 0.7; |
|
|
|
min-width: 50px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.table-header, |
|
|
|
.table-row { |
|
|
|
font-size: 11px; |
|
|
|
padding: 8px 4px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 480px) { |
|
|
|
.material-modal { |
|
|
|
max-width: 100vw; |
|
|
|
max-height: 90vh; |
|
|
|
border-radius: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-no { |
|
|
|
width: 25px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-label-code, |
|
|
|
.material-table .col-material-code { |
|
|
|
flex: 1.3; |
|
|
|
min-width: 65px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-required-qty, |
|
|
|
.material-table .col-inbound-qty { |
|
|
|
flex: 0.6; |
|
|
|
min-width: 55px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.table-header, |
|
|
|
.table-row { |
|
|
|
font-size: 10px; |
|
|
|
padding: 6px 2px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |