Browse Source

2026-05-06

优化
master
fengyuan_yang 2 days ago
parent
commit
e083064650
  1. 160
      src/views/modules/production-pick/productionPickingDetail.vue

160
src/views/modules/production-pick/productionPickingDetail.vue

@ -161,7 +161,13 @@
<div class="col-picked-qty">{{ item.pickedQty || 0 }}</div>
<div class="col-picked-qty">{{ item.scansQty || 0 }}</div>
<div class="col-action">
<span class="row-action-link" @click.stop="openAlternativeDialog(item)">替代</span>
<span
v-if="shouldShowAlternativeAction(item)"
class="row-action-link"
@click.stop="openAlternativeDialog(item)"
>
替代
</span>
</div>
</div>
</div>
@ -296,6 +302,8 @@ export default {
alternativeMaterialList: [],
alternativeListLoading: false,
substituteSourcePartNo: '',
alternativeAvailabilityMap: {},
alternativeAvailabilityReqId: 0,
isRemoveMode: false, //
relatedNo: '',
showStockDialog: false,
@ -459,15 +467,18 @@ export default {
this.materialListLoading = false;
if (data && data.code === 0) {
this.materialList = data.data || [];
this.prefetchAlternativeAvailability(this.materialList);
} else {
this.$message.error(data.msg || '获取物料清单失败');
this.materialList = [];
this.alternativeAvailabilityMap = {};
}
}).catch(error => {
this.materialListLoading = false;
console.error('获取物料清单失败:', error);
this.$message.error('获取物料清单失败');
this.materialList = [];
this.alternativeAvailabilityMap = {};
});
},
@ -477,8 +488,153 @@ export default {
this.hidePartNameTip();
},
getMaterialPartNo(item) {
return item.materialCode || item.partNo || '';
},
normalizeAlternativeIndicator(rawValue) {
if (rawValue === null || rawValue === undefined) {
return null;
}
if (Array.isArray(rawValue)) {
return rawValue.length > 0;
}
if (typeof rawValue === 'boolean') {
return rawValue;
}
if (typeof rawValue === 'number') {
return rawValue > 0;
}
if (typeof rawValue === 'string') {
const normalized = rawValue.trim().toLowerCase();
if (!normalized) {
return null;
}
if (/^-?\d+(\.\d+)?$/.test(normalized)) {
return Number(normalized) > 0;
}
if (['y', 'yes', 'true', '1'].includes(normalized)) {
return true;
}
if (['n', 'no', 'false', '0'].includes(normalized)) {
return false;
}
if (['null', 'none', 'n/a', 'na', '-'].includes(normalized)) {
return false;
}
if (/[|,;]/.test(normalized)) {
return normalized.split(/[|,;]/).some(Boolean);
}
return true;
}
if (typeof rawValue === 'object') {
return Object.keys(rawValue).length > 0;
}
return null;
},
getAlternativeIndicatorFromRow(item) {
const candidateKeys = [
'hasAlternative',
'hasSubstitute',
'alternativeFlag',
'substituteFlag',
'allowAlternative',
'alternativeCount',
'substituteCount',
'alternativeQty',
'substituteQty',
'alternativePartNo',
'alternativePartno',
'substitutePartNo',
'substitutePartno',
'alternativePartList',
'substitutePartList',
'alternativeParts',
'substituteParts'
];
for (const key of candidateKeys) {
if (!Object.prototype.hasOwnProperty.call(item, key)) {
continue;
}
const normalized = this.normalizeAlternativeIndicator(item[key]);
if (normalized !== null) {
return normalized;
}
}
return null;
},
shouldShowAlternativeAction(item) {
const directIndicator = this.getAlternativeIndicatorFromRow(item);
if (directIndicator !== null) {
return directIndicator;
}
const partNo = this.getMaterialPartNo(item);
if (!partNo) {
return false;
}
//
return this.alternativeAvailabilityMap[partNo] !== false;
},
prefetchAlternativeAvailability(materialList) {
this.alternativeAvailabilityReqId += 1;
const currentReqId = this.alternativeAvailabilityReqId;
this.alternativeAvailabilityMap = {};
const uniquePartNosToQuery = new Set();
(materialList || []).forEach(item => {
const partNo = this.getMaterialPartNo(item);
if (!partNo) {
return;
}
const directIndicator = this.getAlternativeIndicatorFromRow(item);
if (directIndicator !== null) {
this.$set(this.alternativeAvailabilityMap, partNo, directIndicator);
return;
}
uniquePartNosToQuery.add(partNo);
});
const uniquePartNos = Array.from(uniquePartNosToQuery);
if (uniquePartNos.length === 0) {
return;
}
const baseParams = {
site: this.outboundInfo.site,
buNo: this.buNo,
outboundNo: this.outboundNo,
warehouseId: getCurrentWarehouse(),
relatedNo: this.relatedNo
};
uniquePartNos.forEach(partNo => {
getBomAlternativePartDetails({
...baseParams,
partNo
}).then(({ data }) => {
if (currentReqId !== this.alternativeAvailabilityReqId) {
return;
}
const hasAlternative = !!(data && data.code === 0 && Array.isArray(data.data) && data.data.length > 0);
this.$set(this.alternativeAvailabilityMap, partNo, hasAlternative);
}).catch(() => {
if (currentReqId !== this.alternativeAvailabilityReqId) {
return;
}
//
this.$set(this.alternativeAvailabilityMap, partNo, true);
});
});
},
openAlternativeDialog(rowItem) {
this.substituteSourcePartNo = rowItem.materialCode || rowItem.partNo;
this.substituteSourcePartNo = this.getMaterialPartNo(rowItem);
if (!this.substituteSourcePartNo) {
this.$message.error('无法识别物料编码');
return;

Loading…
Cancel
Save