分模候选方案
This commit is contained in:
+152
-17
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user