|
|
@@ -9,6 +9,20 @@ import {
|
|
|
exportBomCompareTree
|
|
|
} from '@/api/productionPlan/bomCompare';
|
|
|
|
|
|
+const BOM_TYPE_LABELS = {
|
|
|
+ 1: 'PBOM',
|
|
|
+ 2: 'MBOM',
|
|
|
+ 3: '物料需求清单'
|
|
|
+};
|
|
|
+
|
|
|
+const bomTypeLabel = (bomType) => BOM_TYPE_LABELS[bomType] || 'PBOM';
|
|
|
+
|
|
|
+const BOM_TYPE_TO_SOURCE_TYPE = {
|
|
|
+ 1: 'PBOM',
|
|
|
+ 2: 'MBOM',
|
|
|
+ 3: 'MATERIAL_REQUIREMENTS'
|
|
|
+};
|
|
|
+
|
|
|
const API_TO_UI_TYPE = {
|
|
|
ADDED: 'added',
|
|
|
DELETED: 'removed',
|
|
|
@@ -64,13 +78,15 @@ export default {
|
|
|
},
|
|
|
|
|
|
createSource(item = {}, bomType) {
|
|
|
+ const resolvedBomType = Number(item.bomType || bomType || 1);
|
|
|
return {
|
|
|
bomId: item.bomId || item.id || '',
|
|
|
+ bomType: resolvedBomType,
|
|
|
categoryId: item.categoryId || this.plan.categoryId || '',
|
|
|
code: item.code || item.categoryCode || this.plan.productCode || '-',
|
|
|
name: item.name || item.categoryName || this.plan.productName || '-',
|
|
|
version: item.version || item.versions || '-',
|
|
|
- view: bomType === 1 ? 'PBOM' : 'MBOM',
|
|
|
+ view: bomTypeLabel(resolvedBomType),
|
|
|
factory: item.factories || item.factory || '-',
|
|
|
updatedAt: item.updateTime || item.createTime || '-'
|
|
|
};
|
|
|
@@ -89,7 +105,7 @@ export default {
|
|
|
return {
|
|
|
...item,
|
|
|
bomId,
|
|
|
- bomType,
|
|
|
+ bomType: Number(bomType),
|
|
|
categoryId: item.categoryId || this.plan.categoryId || '',
|
|
|
code,
|
|
|
name,
|
|
|
@@ -104,41 +120,70 @@ export default {
|
|
|
this.$message.warning('当前计划缺少物品 ID,无法查询 PBOM/MBOM 版本');
|
|
|
return;
|
|
|
}
|
|
|
+ await Promise.all([
|
|
|
+ this.loadSideBomOptions('source'),
|
|
|
+ this.loadSideBomOptions('target')
|
|
|
+ ]);
|
|
|
+ await Promise.resolve();
|
|
|
+ if (
|
|
|
+ sequence === this.requestSequence &&
|
|
|
+ this.visible &&
|
|
|
+ this.source.bomId &&
|
|
|
+ this.target.bomId
|
|
|
+ ) {
|
|
|
+ this.runCompare();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ async loadSideBomOptions(side) {
|
|
|
+ const categoryId = this.plan.categoryId;
|
|
|
+ const bomType = Number(this[side].bomType);
|
|
|
+ const optionsKey = side === 'source' ? 'sourceOptions' : 'targetOptions';
|
|
|
+
|
|
|
+ // 物料需求清单:下拉固定为计划编号,不走接口查询
|
|
|
+ if (bomType === 3) {
|
|
|
+ const planCode = this.plan.code || '';
|
|
|
+ const productName = this.plan.productName || '';
|
|
|
+ const fixedOption = {
|
|
|
+ bomId: planCode,
|
|
|
+ bomType: 3,
|
|
|
+ code: planCode,
|
|
|
+ name: productName,
|
|
|
+ version: '-',
|
|
|
+ label: `${planCode}${productName}`
|
|
|
+ };
|
|
|
+ this[optionsKey] = [fixedOption];
|
|
|
+ this[side] = this.createSource(fixedOption, bomType);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!categoryId) {
|
|
|
+ this.$message.warning(
|
|
|
+ `当前计划缺少物品 ID,无法查询 ${bomTypeLabel(bomType)} 版本`
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
this.optionsLoading = true;
|
|
|
+ const sequence = this.requestSequence;
|
|
|
try {
|
|
|
- const [sourceList, targetList] = await Promise.all([
|
|
|
- bomVersionList({ categoryId, bomType: 1, isTemp: 0 }),
|
|
|
- bomVersionList({ categoryId, bomType: 2, isTemp: 0 })
|
|
|
- ]);
|
|
|
+ const list = await bomVersionList({ categoryId, bomType, isTemp: 0 });
|
|
|
if (sequence !== this.requestSequence || !this.visible) return;
|
|
|
- this.sourceOptions = (sourceList || [])
|
|
|
- .filter(
|
|
|
- (item) => item.status === undefined || Number(item.status) === 1
|
|
|
- )
|
|
|
- .map((item) => this.normalizeBomOption(item, 1));
|
|
|
- this.targetOptions = (targetList || [])
|
|
|
+ const options = (list || [])
|
|
|
.filter(
|
|
|
(item) => item.status === undefined || Number(item.status) === 1
|
|
|
)
|
|
|
- .map((item) => this.normalizeBomOption(item, 2));
|
|
|
+ .map((item) => this.normalizeBomOption(item, bomType));
|
|
|
+ this[optionsKey] = options;
|
|
|
|
|
|
- const preferredSource =
|
|
|
- this.sourceOptions.find(
|
|
|
- (item) => String(item.bomId) === String(this.plan.bomCategoryId || '')
|
|
|
- ) || this.sourceOptions[0];
|
|
|
- const preferredTarget =
|
|
|
- this.targetOptions.find(
|
|
|
+ const preferred =
|
|
|
+ options.find(
|
|
|
(item) => String(item.bomId) === String(this.plan.bomCategoryId || '')
|
|
|
- ) || this.targetOptions[0];
|
|
|
- if (preferredSource) this.source = this.createSource(preferredSource, 1);
|
|
|
- if (preferredTarget) this.target = this.createSource(preferredTarget, 2);
|
|
|
-
|
|
|
- if (!this.sourceOptions.length || !this.targetOptions.length) {
|
|
|
- const missing = [];
|
|
|
- if (!this.sourceOptions.length) missing.push('PBOM');
|
|
|
- if (!this.targetOptions.length) missing.push('MBOM');
|
|
|
+ ) || options[0];
|
|
|
+ this[side] = this.createSource(preferred || {}, bomType);
|
|
|
+
|
|
|
+ if (!options.length) {
|
|
|
this.$message.warning(
|
|
|
- `当前产品未维护可用的 ${missing.join('、')} 版本`
|
|
|
+ `当前产品未维护可用的 ${bomTypeLabel(bomType)} 版本`
|
|
|
);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
@@ -147,13 +192,17 @@ export default {
|
|
|
} finally {
|
|
|
if (sequence === this.requestSequence) this.optionsLoading = false;
|
|
|
}
|
|
|
- await Promise.resolve();
|
|
|
- if (
|
|
|
- sequence === this.requestSequence &&
|
|
|
- this.visible &&
|
|
|
- this.sourceOptions.length &&
|
|
|
- this.targetOptions.length
|
|
|
- ) {
|
|
|
+ },
|
|
|
+
|
|
|
+ async handleBomTypeChange(side, bomType) {
|
|
|
+ const normalizedBomType = Number(bomType);
|
|
|
+ this[side].bomType = normalizedBomType;
|
|
|
+ this[side].view = bomTypeLabel(normalizedBomType);
|
|
|
+ this[side].bomId = '';
|
|
|
+ this.cancelPendingRequests();
|
|
|
+ this.resetResultState();
|
|
|
+ await this.loadSideBomOptions(side);
|
|
|
+ if (this.visible && this.source.bomId && this.target.bomId) {
|
|
|
this.runCompare();
|
|
|
}
|
|
|
},
|
|
|
@@ -163,7 +212,7 @@ export default {
|
|
|
const item = options.find(
|
|
|
(option) => String(option.bomId) === String(this[side].bomId)
|
|
|
);
|
|
|
- if (item) this[side] = this.createSource(item, side === 'source' ? 1 : 2);
|
|
|
+ if (item) this[side] = this.createSource(item, item.bomType);
|
|
|
this.cancelPendingRequests();
|
|
|
this.resetResultState();
|
|
|
this.markPending();
|
|
|
@@ -197,13 +246,32 @@ export default {
|
|
|
},
|
|
|
|
|
|
buildStartPayload() {
|
|
|
+ const baseSourceType =
|
|
|
+ BOM_TYPE_TO_SOURCE_TYPE[Number(this.source.bomType)] || 'PBOM';
|
|
|
+ const targetSourceType =
|
|
|
+ BOM_TYPE_TO_SOURCE_TYPE[Number(this.target.bomType)] || 'MBOM';
|
|
|
+ const baseIsMaterial = baseSourceType === 'MATERIAL_REQUIREMENTS';
|
|
|
+ const targetIsMaterial = targetSourceType === 'MATERIAL_REQUIREMENTS';
|
|
|
+
|
|
|
return {
|
|
|
- baseBomId: this.source.bomId || undefined,
|
|
|
- baseCategoryId: this.source.bomId ? undefined : this.source.categoryId,
|
|
|
- baseVersion: this.source.bomId ? undefined : this.source.version,
|
|
|
- targetBomId: this.target.bomId || undefined,
|
|
|
- targetCategoryId: this.target.bomId ? undefined : this.target.categoryId,
|
|
|
- targetVersion: this.target.bomId ? undefined : this.target.version,
|
|
|
+ baseSourceType,
|
|
|
+ targetSourceType,
|
|
|
+ basePlanCode: baseIsMaterial ? this.source.bomId || undefined : undefined,
|
|
|
+ targetPlanCode: targetIsMaterial
|
|
|
+ ? this.target.bomId || undefined
|
|
|
+ : undefined,
|
|
|
+ baseBomId: baseIsMaterial ? undefined : this.source.bomId || undefined,
|
|
|
+ baseCategoryId:
|
|
|
+ !baseIsMaterial && !this.source.bomId ? this.source.categoryId : undefined,
|
|
|
+ baseVersion:
|
|
|
+ !baseIsMaterial && !this.source.bomId ? this.source.version : undefined,
|
|
|
+ targetBomId: targetIsMaterial ? undefined : this.target.bomId || undefined,
|
|
|
+ targetCategoryId:
|
|
|
+ !targetIsMaterial && !this.target.bomId
|
|
|
+ ? this.target.categoryId
|
|
|
+ : undefined,
|
|
|
+ targetVersion:
|
|
|
+ !targetIsMaterial && !this.target.bomId ? this.target.version : undefined,
|
|
|
compareLevel: this.compareLevel === 'single' ? 1 : 2,
|
|
|
compareContent: this.compareMode === 'structure' ? 1 : 2
|
|
|
};
|
|
|
@@ -211,7 +279,11 @@ export default {
|
|
|
|
|
|
async runCompare() {
|
|
|
if (!this.source.bomId || !this.target.bomId) {
|
|
|
- this.$message.warning('请选择基准 PBOM 和目标 MBOM');
|
|
|
+ this.$message.warning(
|
|
|
+ `请选择需要比较的${bomTypeLabel(
|
|
|
+ Number(this.source.bomType)
|
|
|
+ )} 和 ${bomTypeLabel(Number(this.target.bomType))}`
|
|
|
+ );
|
|
|
return;
|
|
|
}
|
|
|
this.cancelPendingRequests();
|
|
|
@@ -243,8 +315,28 @@ export default {
|
|
|
? String(task.status).toUpperCase()
|
|
|
: this.taskStatus;
|
|
|
this.taskMessage = task.message || '';
|
|
|
- if (task.baseBom) this.source = this.createSource(task.baseBom, 1);
|
|
|
- if (task.targetBom) this.target = this.createSource(task.targetBom, 2);
|
|
|
+ if (task.baseBom)
|
|
|
+ this.source = this.createSource(
|
|
|
+ {
|
|
|
+ ...task.baseBom,
|
|
|
+ bomType: this.source.bomType,
|
|
|
+ ...(Number(this.source.bomType) === 3
|
|
|
+ ? { bomId: this.source.bomId }
|
|
|
+ : {})
|
|
|
+ },
|
|
|
+ this.source.bomType
|
|
|
+ );
|
|
|
+ if (task.targetBom)
|
|
|
+ this.target = this.createSource(
|
|
|
+ {
|
|
|
+ ...task.targetBom,
|
|
|
+ bomType: this.target.bomType,
|
|
|
+ ...(Number(this.target.bomType) === 3
|
|
|
+ ? { bomId: this.target.bomId }
|
|
|
+ : {})
|
|
|
+ },
|
|
|
+ this.target.bomType
|
|
|
+ );
|
|
|
if (task.summary) this.summary = this.normalizeSummary(task.summary);
|
|
|
},
|
|
|
|
|
|
@@ -408,8 +500,28 @@ export default {
|
|
|
},
|
|
|
|
|
|
applyTreeResult(tree) {
|
|
|
- if (tree.baseBom) this.source = this.createSource(tree.baseBom, 1);
|
|
|
- if (tree.targetBom) this.target = this.createSource(tree.targetBom, 2);
|
|
|
+ if (tree.baseBom)
|
|
|
+ this.source = this.createSource(
|
|
|
+ {
|
|
|
+ ...tree.baseBom,
|
|
|
+ bomType: this.source.bomType,
|
|
|
+ ...(Number(this.source.bomType) === 3
|
|
|
+ ? { bomId: this.source.bomId }
|
|
|
+ : {})
|
|
|
+ },
|
|
|
+ this.source.bomType
|
|
|
+ );
|
|
|
+ if (tree.targetBom)
|
|
|
+ this.target = this.createSource(
|
|
|
+ {
|
|
|
+ ...tree.targetBom,
|
|
|
+ bomType: this.target.bomType,
|
|
|
+ ...(Number(this.target.bomType) === 3
|
|
|
+ ? { bomId: this.target.bomId }
|
|
|
+ : {})
|
|
|
+ },
|
|
|
+ this.target.bomType
|
|
|
+ );
|
|
|
this.sourceTree = this.normalizeTree(tree.baseTree, 'source');
|
|
|
this.targetTree = this.normalizeTree(tree.targetTree, 'target');
|
|
|
if (tree.summary) this.summary = this.normalizeSummary(tree.summary);
|