From e083064650c194c7274985f4538a3f829f923799 Mon Sep 17 00:00:00 2001
From: fengyuan_yang <1976974459@qq.com>
Date: Fri, 12 Jun 2026 13:20:21 +0800
Subject: [PATCH] =?UTF-8?q?2026-05-06=20=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../productionPickingDetail.vue | 160 +++++++++++++++++-
1 file changed, 158 insertions(+), 2 deletions(-)
diff --git a/src/views/modules/production-pick/productionPickingDetail.vue b/src/views/modules/production-pick/productionPickingDetail.vue
index dcda673..4a8cebe 100644
--- a/src/views/modules/production-pick/productionPickingDetail.vue
+++ b/src/views/modules/production-pick/productionPickingDetail.vue
@@ -161,7 +161,13 @@
{{ item.pickedQty || 0 }}
{{ item.scansQty || 0 }}
- 替代
+
+ 替代
+
@@ -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;