feat (wms/move):新增钢卷匹配进度展示

为入库钢卷功能添加匹配进度界面及对应状态、业务逻辑,实时展示匹配状态、进度占比与当前匹配项结果
This commit is contained in:
王文昊
2026-05-23 10:03:19 +08:00
parent e9de87a7b6
commit 6f5d09beef

View File

@@ -98,6 +98,30 @@
</el-table> </el-table>
</div> </div>
<!-- 匹配进度 -->
<div v-if="step === 'MATCHING'" class="matching-progress-section">
<div class="matching-progress-header">
<i class="el-icon-loading" style="font-size: 20px; color: #409eff;"></i>
<span class="matching-progress-title">正在匹配钢卷...</span>
<span class="matching-progress-percent">{{ matchingPercentage }}%</span>
</div>
<el-progress
:percentage="matchingPercentage"
:stroke-width="18"
:show-text="false"
status="success"
/>
<div class="matching-progress-detail">
<span>{{ matchingProgress }} / {{ matchingTotal }}</span>
<span v-if="currentMatchingText" class="matching-current">
当前: {{ currentMatchingText }}
<el-tag v-if="lastMatchResult === 'matched'" size="mini" type="success">已匹配</el-tag>
<el-tag v-else-if="lastMatchResult === 'conflict'" size="mini" type="warning">冲突</el-tag>
<el-tag v-else-if="lastMatchResult === 'unmatched'" size="mini" type="danger">未匹配</el-tag>
</span>
</div>
</div>
<!-- 标签页内容匹配结果 --> <!-- 标签页内容匹配结果 -->
<div v-if="step === 'REVIEW' || step === 'IMPORTING' || step === 'FINISHED'" class="tabs-section"> <div v-if="step === 'REVIEW' || step === 'IMPORTING' || step === 'FINISHED'" class="tabs-section">
<el-tabs v-model="activeTab" type="border-card"> <el-tabs v-model="activeTab" type="border-card">
@@ -237,6 +261,11 @@
</el-button> </el-button>
</template> </template>
<!-- 匹配中 -->
<template v-if="step === 'MATCHING'">
<el-button disabled>匹配中 {{ matchingProgress }}/{{ matchingTotal }}...</el-button>
</template>
<!-- 导入中禁用关闭 --> <!-- 导入中禁用关闭 -->
<template v-if="step === 'IMPORTING'"> <template v-if="step === 'IMPORTING'">
<el-button disabled>导入中...</el-button> <el-button disabled>导入中...</el-button>
@@ -281,16 +310,27 @@ export default {
importLoading: false, importLoading: false,
importProgress: 0, importProgress: 0,
importedCount: 0, importedCount: 0,
// 匹配进度
matchingTotal: 0,
matchingProgress: 0,
currentMatchingText: '',
lastMatchResult: '',
}; };
}, },
computed: { computed: {
isProcessing() { isProcessing() {
return this.step === 'MATCHING' || this.step === 'IMPORTING'; return this.step === 'MATCHING' || this.step === 'IMPORTING';
}, },
matchingPercentage() {
if (this.matchingTotal === 0) return 0;
return Math.round((this.matchingProgress / this.matchingTotal) * 100);
},
dialogTitle() { dialogTitle() {
switch (this.step) { switch (this.step) {
case 'PARSED': case 'PARSED':
return '导入钢卷 - 数据预览 (' + this.parsedData.length + '条)'; return '导入钢卷 - 数据预览 (' + this.parsedData.length + '条)';
case 'MATCHING':
return '导入钢卷 - 匹配中 (' + this.matchingProgress + '/' + this.matchingTotal + ')';
case 'REVIEW': case 'REVIEW':
case 'IMPORTING': case 'IMPORTING':
case 'FINISHED': case 'FINISHED':
@@ -410,11 +450,18 @@ export default {
this.matchedRows = []; this.matchedRows = [];
this.conflictRows = []; this.conflictRows = [];
this.unmatchedRows = []; this.unmatchedRows = [];
this.matchingTotal = this.parsedData.length;
this.matchingProgress = 0;
this.currentMatchingText = '';
this.lastMatchResult = '';
try { try {
// 逐行匹配 // 逐行匹配
for (const row of this.parsedData) { for (const row of this.parsedData) {
this.currentMatchingText = row.enterCoilNo || row.currentCoilNo;
this.lastMatchResult = '';
await this.matchOneRow(row); await this.matchOneRow(row);
this.matchingProgress++;
} }
this.step = 'REVIEW'; this.step = 'REVIEW';
// 自动切换到第一个有数据的tab // 自动切换到第一个有数据的tab
@@ -447,15 +494,19 @@ export default {
if (list.length === 1) { if (list.length === 1) {
// 场景1精确匹配1条 // 场景1精确匹配1条
this.matchedRows.push({ ...row, matchedCoil: list[0] }); this.matchedRows.push({ ...row, matchedCoil: list[0] });
this.lastMatchResult = 'matched';
} else if (list.length > 1) { } else if (list.length > 1) {
// 场景2匹配到多条需用户选择 // 场景2匹配到多条需用户选择
this.conflictRows.push({ ...row, candidates: list, selectedCoilId: null }); this.conflictRows.push({ ...row, candidates: list, selectedCoilId: null });
this.lastMatchResult = 'conflict';
} else { } else {
// 场景3未匹配 // 场景3未匹配
this.unmatchedRows.push({ ...row, reason: '未找到匹配的钢卷' }); this.unmatchedRows.push({ ...row, reason: '未找到匹配的钢卷' });
this.lastMatchResult = 'unmatched';
} }
} catch (error) { } catch (error) {
this.unmatchedRows.push({ ...row, reason: '查询失败:' + error.message }); this.unmatchedRows.push({ ...row, reason: '查询失败:' + error.message });
this.lastMatchResult = 'unmatched';
} }
}, },
@@ -536,6 +587,10 @@ export default {
this.unmatchedRows = []; this.unmatchedRows = [];
this.importProgress = 0; this.importProgress = 0;
this.importedCount = 0; this.importedCount = 0;
this.matchingTotal = 0;
this.matchingProgress = 0;
this.currentMatchingText = '';
this.lastMatchResult = '';
this.activeTab = 'matched'; this.activeTab = 'matched';
this.$refs.upload && this.$refs.upload.clearFiles(); this.$refs.upload && this.$refs.upload.clearFiles();
} }
@@ -643,6 +698,47 @@ export default {
margin-top: 10px; margin-top: 10px;
} }
/* 匹配进度区域 */
.matching-progress-section {
padding: 30px 20px;
}
.matching-progress-header {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.matching-progress-title {
font-size: 16px;
font-weight: bold;
color: #303133;
margin-left: 8px;
}
.matching-progress-percent {
font-size: 20px;
font-weight: bold;
color: #67c23a;
margin-left: auto;
}
.matching-progress-detail {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 12px;
color: #606266;
font-size: 14px;
}
.matching-current {
display: flex;
align-items: center;
gap: 6px;
color: #909399;
}
/* 标签页区域 */ /* 标签页区域 */
.tabs-section { .tabs-section {
margin-top: 10px; margin-top: 10px;