|
|
|
@ -181,7 +181,7 @@ |
|
|
|
> |
|
|
|
<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-material-code clickable-part" @click="showStockDialogFn(item)">{{item.partNo }}</div> |
|
|
|
<div class="col-required-qty">{{ item.labelCount || 0 }}</div> |
|
|
|
<div class="col-inbound-qty">{{ item.totalinLabels || 0 }}</div> |
|
|
|
</div> |
|
|
|
@ -200,11 +200,64 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 可用库存弹窗 --> |
|
|
|
<div v-if="showStockDialog" class="stock-overlay"> |
|
|
|
<div class="stock-modal"> |
|
|
|
<div class="modal-header"> |
|
|
|
<span class="modal-title">可用库存 - {{ currentPartNo }}</span> |
|
|
|
<i class="el-icon-close close-btn" @click="closeStockDialog"></i> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="modal-body"> |
|
|
|
<!-- 加载状态 --> |
|
|
|
<div v-if="stockLoading" class="loading-container"> |
|
|
|
<i class="el-icon-loading"></i> |
|
|
|
<span>加载中...</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 库存表格 --> |
|
|
|
<div v-else-if="stockList.length > 0" class="stock-table"> |
|
|
|
<div class="table-header"> |
|
|
|
<div class="col-roll-no">标签条码</div> |
|
|
|
<div class="col-qty">数量</div> |
|
|
|
<div class="col-location">库位</div> |
|
|
|
<div class="col-batch">合约号码</div> |
|
|
|
<div class="col-date">入库日期</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="table-body"> |
|
|
|
<div |
|
|
|
v-for="(item, index) in stockList" |
|
|
|
:key="index" |
|
|
|
class="table-row" |
|
|
|
> |
|
|
|
<div class="col-roll-no">{{ item.rollNo }}</div> |
|
|
|
<div class="col-qty">{{ item.rollQty }} <span class="unit-text">{{ item.um }}</span></div> |
|
|
|
<div class="col-location">{{ item.location }}</div> |
|
|
|
<div class="col-batch">{{ item.batchNo }}</div> |
|
|
|
<div class="col-date">{{ item.daysInStock }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 空数据状态 --> |
|
|
|
<div v-else class="empty-stock"> |
|
|
|
<i class="el-icon-box"></i> |
|
|
|
<p>暂无可用库存</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="modal-footer"> |
|
|
|
<button class="btn-close" @click="closeStockDialog">关闭</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel, getMaterialList, getScannedLabelList } from "@/api/inbound.js"; |
|
|
|
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel, getMaterialList, getScannedLabelList, getInventoryStock } from "@/api/inbound.js"; |
|
|
|
import { getCurrentWarehouse } from '@/utils' |
|
|
|
import moment from 'moment'; |
|
|
|
export default { |
|
|
|
@ -220,7 +273,12 @@ export default { |
|
|
|
showMaterialDialog: false, |
|
|
|
materialList: [], |
|
|
|
materialListLoading: false, |
|
|
|
isRemoveMode: false // 默认为添加模式 |
|
|
|
isRemoveMode: false, // 默认为添加模式 |
|
|
|
// 可用库存弹窗相关 |
|
|
|
showStockDialog: false, |
|
|
|
stockList: [], |
|
|
|
stockLoading: false, |
|
|
|
currentPartNo: '' |
|
|
|
}; |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
@ -411,6 +469,49 @@ export default { |
|
|
|
this.showMaterialDialog = false; |
|
|
|
}, |
|
|
|
|
|
|
|
// 显示可用库存弹窗 |
|
|
|
showStockDialogFn(item) { |
|
|
|
this.currentPartNo = item.partNo; |
|
|
|
this.showStockDialog = true; |
|
|
|
this.loadInventoryStock(this.currentPartNo); |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载物料可用库存 |
|
|
|
loadInventoryStock(partNo) { |
|
|
|
this.stockLoading = true; |
|
|
|
const params = { |
|
|
|
site: this.materialInfo.site, |
|
|
|
notifyNo: this.inboundNo, |
|
|
|
notifyType: '采购入库', |
|
|
|
orderNo: '', |
|
|
|
orderLineNo: '', |
|
|
|
partNo: partNo, |
|
|
|
warehouseId: getCurrentWarehouse() |
|
|
|
}; |
|
|
|
|
|
|
|
getInventoryStock(params).then(({ data }) => { |
|
|
|
this.stockLoading = false; |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.stockList = data.data || []; |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '获取可用库存失败'); |
|
|
|
this.stockList = []; |
|
|
|
} |
|
|
|
}).catch(error => { |
|
|
|
this.stockLoading = false; |
|
|
|
console.error('获取可用库存失败:', error); |
|
|
|
this.$message.error('获取可用库存失败'); |
|
|
|
this.stockList = []; |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 关闭可用库存弹窗 |
|
|
|
closeStockDialog() { |
|
|
|
this.showStockDialog = false; |
|
|
|
this.stockList = []; |
|
|
|
this.currentPartNo = ''; |
|
|
|
}, |
|
|
|
|
|
|
|
// 加载入库单详情 |
|
|
|
loadInboundDetails() { |
|
|
|
const params = { |
|
|
|
@ -1214,6 +1315,23 @@ export default { |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
|
|
|
|
/* 可点击的物料编码样式 */ |
|
|
|
.clickable-part { |
|
|
|
color: #17B3A3; |
|
|
|
font-weight: 500; |
|
|
|
cursor: pointer; |
|
|
|
text-decoration: underline; |
|
|
|
transition: color 0.2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.clickable-part:hover { |
|
|
|
color: #0d8f7f; |
|
|
|
} |
|
|
|
|
|
|
|
.clickable-part:active { |
|
|
|
color: #0a7a6c; |
|
|
|
} |
|
|
|
|
|
|
|
.material-table .col-required-qty { |
|
|
|
flex: 0.8; |
|
|
|
text-align: center; |
|
|
|
@ -1292,6 +1410,234 @@ export default { |
|
|
|
font-size: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 可用库存弹窗样式 */ |
|
|
|
.stock-overlay { |
|
|
|
position: fixed; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
background: rgba(0, 0, 0, 0.5); |
|
|
|
z-index: 10000; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 20px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-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; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-modal .modal-header { |
|
|
|
background: #17B3A3; |
|
|
|
color: white; |
|
|
|
padding: 5px 16px; |
|
|
|
display: flex; |
|
|
|
justify-content: space-between; |
|
|
|
align-items: center; |
|
|
|
min-height: 28px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-modal .modal-title { |
|
|
|
font-size: 16px; |
|
|
|
font-weight: 500; |
|
|
|
margin: 0; |
|
|
|
line-height: 1.2; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-modal .modal-body { |
|
|
|
flex: 1; |
|
|
|
overflow: auto; |
|
|
|
padding: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table { |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .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; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-body { |
|
|
|
max-height: 400px; |
|
|
|
overflow-y: auto; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-row { |
|
|
|
display: flex; |
|
|
|
padding: 10px 6px; |
|
|
|
border-bottom: 1px solid #f0f0f0; |
|
|
|
font-size: 12px; |
|
|
|
color: #333; |
|
|
|
transition: background-color 0.2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-row:hover { |
|
|
|
background-color: #f8f9fa; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-row:last-child { |
|
|
|
border-bottom: none; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-roll-no { |
|
|
|
flex: 1.5; |
|
|
|
text-align: center; |
|
|
|
min-width: 100px; |
|
|
|
font-size: 12px; |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-qty { |
|
|
|
flex: 0.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 60px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 单位文本样式 */ |
|
|
|
.unit-text { |
|
|
|
color: #999; |
|
|
|
font-size: 11px; |
|
|
|
margin-left: 2px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-location { |
|
|
|
flex: 0.8; |
|
|
|
text-align: center; |
|
|
|
min-width: 60px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-batch { |
|
|
|
flex: 1; |
|
|
|
text-align: center; |
|
|
|
min-width: 80px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-date { |
|
|
|
flex: 1; |
|
|
|
text-align: center; |
|
|
|
min-width: 80px; |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-modal .modal-footer { |
|
|
|
padding: 15px 20px; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
border-top: 1px solid #f0f0f0; |
|
|
|
} |
|
|
|
|
|
|
|
/* 空数据状态样式 */ |
|
|
|
.empty-stock { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 60px 20px; |
|
|
|
color: #999; |
|
|
|
} |
|
|
|
|
|
|
|
.empty-stock i { |
|
|
|
font-size: 48px; |
|
|
|
margin-bottom: 16px; |
|
|
|
color: #ddd; |
|
|
|
} |
|
|
|
|
|
|
|
.empty-stock p { |
|
|
|
margin: 0; |
|
|
|
font-size: 14px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式设计 - 可用库存弹窗 */ |
|
|
|
@media (max-width: 768px) { |
|
|
|
.stock-modal { |
|
|
|
max-width: 98vw; |
|
|
|
max-height: 85vh; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-roll-no { |
|
|
|
flex: 1.3; |
|
|
|
min-width: 85px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-qty, |
|
|
|
.stock-table .col-location { |
|
|
|
flex: 0.7; |
|
|
|
min-width: 50px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-batch, |
|
|
|
.stock-table .col-date { |
|
|
|
flex: 0.9; |
|
|
|
min-width: 65px; |
|
|
|
font-size: 11px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-header, |
|
|
|
.stock-table .table-row { |
|
|
|
font-size: 11px; |
|
|
|
padding: 8px 4px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 480px) { |
|
|
|
.stock-modal { |
|
|
|
max-width: 100vw; |
|
|
|
max-height: 90vh; |
|
|
|
border-radius: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-roll-no { |
|
|
|
flex: 1.2; |
|
|
|
min-width: 70px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-qty, |
|
|
|
.stock-table .col-location { |
|
|
|
flex: 0.6; |
|
|
|
min-width: 45px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .col-batch, |
|
|
|
.stock-table .col-date { |
|
|
|
flex: 0.8; |
|
|
|
min-width: 55px; |
|
|
|
font-size: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.stock-table .table-header, |
|
|
|
.stock-table .table-row { |
|
|
|
font-size: 10px; |
|
|
|
padding: 6px 2px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式设计 - 物料清单弹窗 */ |
|
|
|
@media (max-width: 768px) { |
|
|
|
.material-modal { |
|
|
|
|