分模候选方案

This commit is contained in:
2026-04-23 23:37:39 +08:00
parent 0bdfc7f7d5
commit c1f6b6e827
16 changed files with 1302 additions and 497 deletions
+152 -17
View File
@@ -1220,7 +1220,8 @@ const ResultView = {
const state = reactive({
task: null,
loading: true,
error: ''
error: '',
selectedSchemeId: null
});
const loadTask = async () => {
@@ -1232,6 +1233,11 @@ const ResultView = {
console.log('cavity_data:', state.task.cavity_data);
console.log('analysis_result:', state.task.analysis_result);
console.log('geometry_data:', state.task.geometry_data);
if (state.task?.best_scheme_id) {
state.selectedSchemeId = state.task.best_scheme_id;
} else if (state.task?.candidate_schemes?.length) {
state.selectedSchemeId = state.task.candidate_schemes[0].scheme_id;
}
} catch (e) {
state.error = handleApiError(e, '加载任务详情');
} finally {
@@ -1261,6 +1267,27 @@ const ResultView = {
return material === 'aluminum_foam';
};
const candidateSchemes = computed(() => state.task?.candidate_schemes || []);
const selectedScheme = computed(() => {
if (!candidateSchemes.value.length) return null;
return candidateSchemes.value.find(s => s.scheme_id === state.selectedSchemeId) || candidateSchemes.value[0];
});
const selectedCavityData = computed(() => selectedScheme.value?.cavity_data || state.task?.cavity_data || null);
const selectedKeyInfo = computed(() => selectedScheme.value?.key_info || state.task?.key_info || null);
const selectedHtmlFile = computed(() => selectedScheme.value?.html_file || state.task?.html_file || '');
const selectScheme = (schemeId) => {
state.selectedSchemeId = schemeId;
};
const formatSchemeDirection = (scheme) => {
if (!scheme) return 'N/A';
if (scheme.parting?.axis) return `${scheme.parting.axis} 轴`;
const dir = scheme.parting?.direction;
if (!Array.isArray(dir)) return 'N/A';
return `[${dir.map(v => Number(v).toFixed(2)).join(', ')}]`;
};
const exportCAD = async (format) => {
try {
const taskId = route.params.taskId;
@@ -1293,7 +1320,22 @@ const ResultView = {
}
};
return { state, formatFileSize, formatDateTime, formatNumber, getPriorityText, isFoamMaterial, exportCAD };
return {
state,
candidateSchemes,
selectedScheme,
selectedCavityData,
selectedKeyInfo,
selectedHtmlFile,
formatFileSize,
formatDateTime,
formatNumber,
getPriorityText,
isFoamMaterial,
exportCAD,
selectScheme,
formatSchemeDirection
};
},
template: `
<div class="page-container">
@@ -1378,7 +1420,97 @@ const ResultView = {
</div>
</div>
<div v-if="state.task.cavity_data || state.task.key_info" class="viewer-section">
<div v-if="candidateSchemes.length" class="viewer-section">
<h3>候选分模方案</h3>
<div class="result-grid">
<div
v-for="scheme in candidateSchemes"
:key="scheme.scheme_id"
class="result-card"
:style="state.selectedSchemeId === scheme.scheme_id ? 'border: 2px solid var(--primary-color);' : ''"
>
<div class="summary-header">
<h4>{{ scheme.title || scheme.scheme_id }}</h4>
<span class="badge badge-info">总分 {{ formatNumber(scheme.score) }}</span>
</div>
<div class="info-list">
<div class="info-item">
<span class="info-label">分型方向</span>
<span class="info-value">{{ formatSchemeDirection(scheme) }}</span>
</div>
<div class="info-item">
<span class="info-label">分型面位置</span>
<span class="info-value">{{ scheme.offset_label || '中面' }}</span>
</div>
<div class="info-item">
<span class="info-label">候选优先级</span>
<span class="info-value">{{ formatNumber(scheme.priority_score || 0) }}</span>
</div>
<div class="info-item">
<span class="info-label">法向匹配度</span>
<span class="info-value">{{ formatNumber(scheme.normal_alignment_score || 0) }}</span>
</div>
<div class="info-item">
<span class="info-label">方法</span>
<span class="info-value">{{ scheme.method || 'rule_based' }}</span>
</div>
<div class="info-item">
<span class="info-label">方案说明</span>
<span class="info-value">{{ scheme.summary || scheme.reason || '暂无说明' }}</span>
</div>
<div class="info-item">
<span class="info-label">可制造性</span>
<span class="info-value">{{ formatNumber(scheme.score_breakdown?.manufacturability || 0) }}</span>
</div>
<div class="info-item">
<span class="info-label">分型质量</span>
<span class="info-value">{{ formatNumber(scheme.score_breakdown?.parting_quality || 0) }}</span>
</div>
<div class="info-item">
<span class="info-label">风险得分</span>
<span class="info-value">{{ formatNumber(scheme.score_breakdown?.risk || 0) }}</span>
</div>
</div>
<button class="btn-sm btn-primary" @click="selectScheme(scheme.scheme_id)">查看此方案</button>
</div>
</div>
</div>
<div v-if="candidateSchemes.length > 1" class="viewer-section">
<h3>方案对比</h3>
<div class="result-card full-width">
<table class="data-table">
<thead>
<tr>
<th>方案</th>
<th>方向</th>
<th>位置</th>
<th>总分</th>
<th>法向匹配</th>
<th>可制造性</th>
<th>分型质量</th>
<th>倒扣数</th>
<th>锁模力</th>
</tr>
</thead>
<tbody>
<tr v-for="scheme in candidateSchemes" :key="'cmp-' + scheme.scheme_id">
<td>{{ scheme.title || scheme.scheme_id }}</td>
<td>{{ formatSchemeDirection(scheme) }}</td>
<td>{{ scheme.offset_label || '中面' }}</td>
<td>{{ formatNumber(scheme.score) }}</td>
<td>{{ formatNumber(scheme.normal_alignment_score || 0) }}</td>
<td>{{ formatNumber(scheme.score_breakdown?.manufacturability || 0) }}</td>
<td>{{ formatNumber(scheme.score_breakdown?.parting_quality || 0) }}</td>
<td>{{ scheme.key_info?.quality_considerations?.undercut_count || 0 }}</td>
<td>{{ scheme.cavity_data?.manufacturing_info?.estimated_clamping_force || 'N/A' }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="selectedCavityData || selectedKeyInfo" class="viewer-section">
<h3>模具信息</h3>
<div class="result-grid">
<div class="result-card">
@@ -1386,29 +1518,29 @@ const ResultView = {
<div class="info-list">
<div class="info-item">
<span class="info-label">零件名称</span>
<span class="info-value">{{ state.task.cavity_data?.metadata?.part_name || state.task.key_info?.metadata?.part_name || 'N/A' }}</span>
<span class="info-value">{{ selectedCavityData?.metadata?.part_name || selectedKeyInfo?.metadata?.part_name || 'N/A' }}</span>
</div>
<div class="info-item">
<span class="info-label">材料</span>
<span class="info-value">{{ state.task.cavity_data?.metadata?.material || state.task.key_info?.metadata?.material || 'N/A' }}</span>
<span class="info-value">{{ selectedCavityData?.metadata?.material || selectedKeyInfo?.metadata?.material || 'N/A' }}</span>
</div>
</div>
</div>
<div class="result-card" v-if="state.task.cavity_data?.mold_cavities || state.task.key_info?.mold_cavities">
<div class="result-card" v-if="selectedCavityData?.mold_cavities || selectedKeyInfo?.mold_cavities">
<h4>型腔信息</h4>
<div class="info-list">
<div class="info-item">
<span class="info-label">型腔数量</span>
<span class="info-value">{{ Object.keys(state.task.cavity_data?.mold_cavities || state.task.key_info?.mold_cavities || {}).length }}</span>
<span class="info-value">{{ Object.keys(selectedCavityData?.mold_cavities || selectedKeyInfo?.mold_cavities || {}).length }}</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="state.task.html_file" class="viewer-section">
<div v-if="selectedHtmlFile" class="viewer-section">
<h3>3D 预览</h3>
<iframe :src="state.task.html_file" class="viewer-frame"></iframe>
<iframe :src="selectedHtmlFile" class="viewer-frame"></iframe>
</div>
<div v-if="state.task.analysis_result" class="viewer-section">
@@ -1544,15 +1676,18 @@ const ResultView = {
<div class="info-list">
<div class="info-item">
<span class="info-label">型腔数量建议</span>
<span class="info-value">{{ state.task.cavity_data?.mold_cavities ? Object.keys(state.task.cavity_data.mold_cavities).length : 1 }} 腔</span>
<span class="info-value">{{ selectedCavityData?.mold_cavities ? Object.keys(selectedCavityData.mold_cavities).length : 1 }} 腔</span>
</div>
<div class="info-item">
<span class="info-label">模架尺寸</span>
<span class="info-value">{{ state.task.key_info?.mold_parameters?.mold_size || '基于泡沫外形自动计算' }}</span>
<span class="info-value">{{ selectedCavityData?.manufacturing_info?.estimated_mold_size ?
(selectedCavityData.manufacturing_info.estimated_mold_size.length || 0) + ' × ' +
(selectedCavityData.manufacturing_info.estimated_mold_size.width || 0) + ' × ' +
(selectedCavityData.manufacturing_info.estimated_mold_size.height || 0) + ' mm' : '基于泡沫外形自动计算' }}</span>
</div>
<div class="info-item" v-if="state.task.key_info?.geometric_characteristics">
<div class="info-item" v-if="selectedCavityData?.manufacturing_info || selectedKeyInfo?.geometric_characteristics">
<span class="info-label">预估锁模力</span>
<span class="info-value">{{ state.task.key_info.geometric_characteristics.estimated_clamping_force || '自动计算' }} 吨</span>
<span class="info-value">{{ selectedCavityData?.manufacturing_info?.estimated_clamping_force || '自动计算' }}</span>
</div>
<div class="info-item">
<span class="info-label">顶出系统</span>
@@ -1578,13 +1713,13 @@ const ResultView = {
<span class="info-label">壁厚均匀性</span>
<span class="info-value">{{ (state.task.analysis_result.quality_metrics.wall_uniformity * 100)?.toFixed(1) || 'N/A' }}%</span>
</div>
<div class="info-item" v-if="state.task.key_info?.quality_considerations">
<div class="info-item" v-if="selectedKeyInfo?.quality_considerations">
<span class="info-label">翘曲风险</span>
<span class="info-value">{{ state.task.key_info.quality_considerations.warpage_risk || '低风险' }}</span>
<span class="info-value">{{ selectedKeyInfo.quality_considerations.warpage_risk || '低风险' }}</span>
</div>
<div class="info-item" v-if="state.task.key_info?.quality_considerations">
<div class="info-item" v-if="selectedKeyInfo?.quality_considerations">
<span class="info-label">潜在焊缝线</span>
<span class="info-value">{{ state.task.key_info.quality_considerations.potential_weld_lines || 0 }} 条</span>
<span class="info-value">{{ selectedKeyInfo.quality_considerations.potential_weld_lines || 0 }} 条</span>
</div>
</div>
</div>