This commit is contained in:
2026-05-14 18:09:12 +08:00
parent 224330598a
commit 390f3e62e1
2 changed files with 183 additions and 78 deletions
+76
View File
@@ -828,6 +828,51 @@ optgroup {
padding: 0 var(--space-4) var(--space-4); padding: 0 var(--space-4) var(--space-4);
} }
.advanced-param-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-4);
margin-top: var(--space-4);
}
.param-input-card {
background: var(--bg-secondary);
border: 1px solid var(--border-light);
border-radius: var(--radius-lg);
padding: var(--space-4);
}
.param-input-row {
display: flex;
align-items: center;
gap: var(--space-3);
}
.param-number-input {
flex: 1;
}
.param-unit {
min-width: 2.5rem;
font-size: var(--text-sm);
color: var(--text-secondary);
font-weight: var(--font-semibold);
}
.param-meta-row {
display: flex;
gap: var(--space-3);
flex-wrap: wrap;
margin-top: var(--space-2);
}
.param-hint {
margin-top: var(--space-2);
font-size: var(--text-xs);
color: var(--text-tertiary);
line-height: 1.6;
}
.upload-submit-btn { .upload-submit-btn {
width: 100%; width: 100%;
margin-top: var(--space-4); margin-top: var(--space-4);
@@ -1311,6 +1356,33 @@ optgroup {
margin-bottom: var(--space-6); margin-bottom: var(--space-6);
} }
.result-anchor-nav {
display: flex;
gap: var(--space-2);
flex-wrap: wrap;
margin-bottom: var(--space-5);
}
.anchor-pill {
display: inline-flex;
align-items: center;
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-full);
background: var(--bg-primary);
border: 1px solid var(--border-default);
color: var(--text-secondary);
font-size: var(--text-sm);
font-weight: var(--font-medium);
text-decoration: none;
transition: all var(--duration-fast) var(--ease-default);
}
.anchor-pill:hover {
background: var(--primary-50);
border-color: var(--primary-200);
color: var(--primary-700);
}
.single-scheme-grid { .single-scheme-grid {
grid-template-columns: 1fr !important; grid-template-columns: 1fr !important;
} }
@@ -2841,6 +2913,10 @@ select.form-input {
.upload-layout { .upload-layout {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.advanced-param-grid {
grid-template-columns: 1fr;
}
} }
/* ================================ /* ================================
+107 -78
View File
@@ -1156,6 +1156,49 @@ const MoldInsightView = {
loadHistory(); loadHistory();
}); });
const moldParamFields = [
{
key: 'draftAngle',
label: '拔模角',
unit: '°',
min: 1,
max: 10,
step: 0.5,
defaultValue: 2.0,
hint: '常规注塑件建议从 1.5° 到 3° 起步'
},
{
key: 'shrinkageRate',
label: '收缩率',
unit: '%',
min: 0.5,
max: 3.0,
step: 0.1,
defaultValue: 0.5,
hint: '按材料牌号校核,默认值用于首轮方案评估'
},
{
key: 'partingPrecision',
label: '分型精度',
unit: 'mm',
min: 0.01,
max: 1.0,
step: 0.01,
defaultValue: 0.1,
hint: '用于控制分型面拟合与边界容差'
},
{
key: 'cavityMatch',
label: '型腔匹配度',
unit: '%',
min: 80,
max: 100,
step: 1,
defaultValue: 95,
hint: '数值越高越偏向紧配合与严格封合'
}
];
return { return {
state, state,
handleFileChange, handleFileChange,
@@ -1164,6 +1207,7 @@ const MoldInsightView = {
formatFileSize, formatFileSize,
formatDateTime, formatDateTime,
formatNumber, formatNumber,
moldParamFields,
toggleFileHistory, toggleFileHistory,
viewResult viewResult
}; };
@@ -1248,31 +1292,25 @@ const MoldInsightView = {
<summary>高级工艺参数</summary> <summary>高级工艺参数</summary>
<div class="advanced-params-body"> <div class="advanced-params-body">
<div class="inline-note">默认值适用于多数注塑件;仅在已知工艺约束时再调整。</div> <div class="inline-note">默认值适用于多数注塑件;仅在已知工艺约束时再调整。</div>
<div class="form-row"> <div class="advanced-param-grid">
<div class="form-group"> <div class="param-input-card" v-for="field in moldParamFields" :key="field.key">
<label class="form-label">拔模角 (°)</label> <label class="form-label">{{ field.label }}</label>
<input type="range" v-model.number="state.moldParams.draftAngle" min="1" max="10" step="0.5" class="form-range"> <div class="param-input-row">
<span class="range-value">{{ state.moldParams.draftAngle }}°</span> <input
</div> type="number"
class="form-input param-number-input"
<div class="form-group"> v-model.number="state.moldParams[field.key]"
<label class="form-label">收缩率 (%)</label> :min="field.min"
<input type="range" v-model.number="state.moldParams.shrinkageRate" min="0.5" max="3.0" step="0.1" class="form-range"> :max="field.max"
<span class="range-value">{{ state.moldParams.shrinkageRate }}%</span> :step="field.step"
</div> >
</div> <span class="param-unit">{{ field.unit }}</span>
</div>
<div class="form-row"> <div class="param-meta-row">
<div class="form-group"> <span class="range-value">默认 {{ field.defaultValue }}{{ field.unit }}</span>
<label class="form-label">分型精度 (mm)</label> <span class="range-value">范围 {{ field.min }} - {{ field.max }}{{ field.unit }}</span>
<input type="range" v-model.number="state.moldParams.partingPrecision" min="0.01" max="1.0" step="0.01" class="form-range"> </div>
<span class="range-value">{{ state.moldParams.partingPrecision }} mm</span> <div class="param-hint">{{ field.hint }}</div>
</div>
<div class="form-group">
<label class="form-label">型腔匹配度 (%)</label>
<input type="range" v-model.number="state.moldParams.cavityMatch" min="80" max="100" step="1" class="form-range">
<span class="range-value">{{ state.moldParams.cavityMatch }}%</span>
</div> </div>
</div> </div>
</div> </div>
@@ -1497,6 +1535,15 @@ const ResultView = {
if (selectedDfmCount.value >= 2) return '中风险'; if (selectedDfmCount.value >= 2) return '中风险';
return '低风险'; return '低风险';
}); });
const resultAnchorLinks = [
{ id: 'candidate-schemes', label: '方案' },
{ id: 'engineering-summary', label: '工程摘要' },
{ id: 'dfm-check', label: 'DFM' },
{ id: 'preview-3d', label: '预览' },
{ id: 'export-cam', label: '导出/CAM' },
{ id: 'analysis-details', label: '分析详情' },
{ id: 'diagnostic-info', label: '诊断' }
];
const selectScheme = (schemeId) => { const selectScheme = (schemeId) => {
state.selectedSchemeId = schemeId; state.selectedSchemeId = schemeId;
@@ -1659,6 +1706,7 @@ const ResultView = {
selectedDfmCount, selectedDfmCount,
selectedCavityCount, selectedCavityCount,
selectedRiskLabel, selectedRiskLabel,
resultAnchorLinks,
formatFileSize, formatFileSize,
formatDateTime, formatDateTime,
formatNumber, formatNumber,
@@ -1697,6 +1745,17 @@ const ResultView = {
</span> </span>
</div> </div>
<div class="result-anchor-nav">
<a
v-for="anchor in resultAnchorLinks"
:key="anchor.id"
class="anchor-pill"
:href="'#' + anchor.id"
>
{{ anchor.label }}
</a>
</div>
<div class="result-grid result-priority-grid"> <div class="result-grid result-priority-grid">
<div class="result-card result-card-highlight"> <div class="result-card result-card-highlight">
<div class="summary-header"> <div class="summary-header">
@@ -1822,7 +1881,7 @@ const ResultView = {
</div> </div>
</div> </div>
<div v-if="candidateSchemes.length" class="viewer-section"> <div id="candidate-schemes" v-if="candidateSchemes.length" class="viewer-section">
<h3>候选分模方案</h3> <h3>候选分模方案</h3>
<div class="inline-note">先切换并确认推荐方案,再进入后续工程判断、导出与 CAM。</div> <div class="inline-note">先切换并确认推荐方案,再进入后续工程判断、导出与 CAM。</div>
<div :class="['result-grid', hasSingleScheme ? 'single-scheme-grid' : '']"> <div :class="['result-grid', hasSingleScheme ? 'single-scheme-grid' : '']">
@@ -1938,7 +1997,7 @@ const ResultView = {
</div> </div>
</details> </details>
<div v-if="selectedCavityData || selectedKeyInfo" class="viewer-section"> <div id="engineering-summary" v-if="selectedCavityData || selectedKeyInfo" class="viewer-section">
<h3>工程摘要</h3> <h3>工程摘要</h3>
<div class="result-grid"> <div class="result-grid">
<div class="result-card"> <div class="result-card">
@@ -2003,7 +2062,7 @@ const ResultView = {
</div> </div>
</div> </div>
<div class="viewer-section"> <div id="dfm-check" class="viewer-section">
<h3>DFM 检查</h3> <h3>DFM 检查</h3>
<div v-if="!selectedDfmViolations.length" class="inline-alert inline-alert-warning"> <div v-if="!selectedDfmViolations.length" class="inline-alert inline-alert-warning">
<div class="inline-alert-title">未发现显著 DFM 违规项</div> <div class="inline-alert-title">未发现显著 DFM 违规项</div>
@@ -2029,7 +2088,7 @@ const ResultView = {
</div> </div>
</div> </div>
<div v-if="selectedHtmlFile" class="viewer-section"> <div id="preview-3d" v-if="selectedHtmlFile" class="viewer-section">
<h3>3D 预览</h3> <h3>3D 预览</h3>
<div v-if="state.previewStatus === 'error'" class="inline-alert inline-alert-warning" style="margin-bottom: var(--space-3);"> <div v-if="state.previewStatus === 'error'" class="inline-alert inline-alert-warning" style="margin-bottom: var(--space-3);">
<div class="inline-alert-title">预览加载失败</div> <div class="inline-alert-title">预览加载失败</div>
@@ -2044,7 +2103,7 @@ const ResultView = {
></iframe> ></iframe>
</div> </div>
<div v-else class="viewer-section"> <div id="preview-3d" v-else class="viewer-section">
<h3>3D 预览</h3> <h3>3D 预览</h3>
<div class="inline-alert inline-alert-warning"> <div class="inline-alert inline-alert-warning">
<div class="inline-alert-title">预览未生成</div> <div class="inline-alert-title">预览未生成</div>
@@ -2052,7 +2111,7 @@ const ResultView = {
</div> </div>
</div> </div>
<div class="viewer-section"> <div id="export-cam" class="viewer-section">
<h3>导出与 CAM</h3> <h3>导出与 CAM</h3>
<div class="result-card" style="margin-bottom: var(--space-4);"> <div class="result-card" style="margin-bottom: var(--space-4);">
<h4>CAM 参数</h4> <h4>CAM 参数</h4>
@@ -2165,7 +2224,7 @@ const ResultView = {
</template> </template>
</div> </div>
<div v-if="state.task.analysis_result" class="viewer-section"> <div id="analysis-details" v-if="state.task.analysis_result" class="viewer-section">
<h3>分析结果详情</h3> <h3>分析结果详情</h3>
<div class="analysis-summary" v-if="state.task.analysis_result.analysis_summary"> <div class="analysis-summary" v-if="state.task.analysis_result.analysis_summary">
<div class="summary-header"> <div class="summary-header">
@@ -2179,7 +2238,7 @@ const ResultView = {
<div class="result-grid"> <div class="result-grid">
<div class="result-card full-width"> <div class="result-card full-width">
<h4>1. 产品特征识别</h4> <h4>几何与特征摘要</h4>
<div class="info-list"> <div class="info-list">
<div class="info-item"> <div class="info-item">
<span class="info-label">整体轮廓和尺寸比例</span> <span class="info-label">整体轮廓和尺寸比例</span>
@@ -2219,7 +2278,7 @@ const ResultView = {
</div> </div>
<div class="result-card full-width"> <div class="result-card full-width">
<h4>2. 注塑模设计决策</h4> <h4>工程建议与质量指标</h4>
<div class="info-list"> <div class="info-list">
<div class="info-item"> <div class="info-item">
<span class="info-label">高优先级工艺建议</span> <span class="info-label">高优先级工艺建议</span>
@@ -2245,50 +2304,9 @@ const ResultView = {
<span class="info-label">分型面选择</span> <span class="info-label">分型面选择</span>
<span class="info-value">基于产品几何:自动推荐最优分型面</span> <span class="info-value">基于产品几何:自动推荐最优分型面</span>
</div> </div>
<div class="info-item" v-if="selectedCavityData?.manufacturing_info?.estimated_mold_size">
<!-- 设计建议列表 -->
<div class="recommendations-section" v-if="sortedRecommendations.length">
<h5>详细设计建议</h5>
<div class="recommendations-list">
<div v-for="rec in sortedRecommendations" :key="rec.type" class="recommendation-item" :class="rec.priority">
<span class="priority-badge" :class="rec.priority">{{ getPriorityText(rec.priority) }}</span>
<span class="recommendation-text">{{ rec.description }}</span>
<span class="recommendation-reason" v-if="rec.reason">({{ rec.reason }})</span>
</div>
</div>
</div>
</div>
</div>
<div class="result-card full-width">
<h4>3. 模具工程决策</h4>
<div class="info-list">
<div class="info-item">
<span class="info-label">型腔数量建议</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-label">模架尺寸</span>
<span class="info-value">{{ selectedCavityData?.manufacturing_info?.estimated_mold_size ? <span class="info-value">{{ (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>
(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="selectedCavityData?.manufacturing_info || selectedKeyInfo?.geometric_characteristics">
<span class="info-label">预估锁模力</span>
<span class="info-value">{{ selectedCavityData?.manufacturing_info?.estimated_clamping_force || '自动计算' }}</span>
</div>
<div class="info-item">
<span class="info-label">顶出系统</span>
<span class="info-value">顶针顶出(自动布局)</span>
</div>
<div class="info-item">
<span class="info-label">冷却水路设计</span>
<span class="info-value">{{ state.task.analysis_result.geometry_data?.volume > 1000000 ? '需要冷却水路' : '自然冷却' }}</span>
</div>
<div class="info-item">
<span class="info-label">材料选择</span>
<span class="info-value">{{ state.task.analysis_result.quality_metrics?.volume ? '根据产量和精度自动推荐' : '7075 铝合金' }}</span>
</div> </div>
<div class="info-item" v-if="state.task.analysis_result.quality_metrics"> <div class="info-item" v-if="state.task.analysis_result.quality_metrics">
<span class="info-label">体积利用率</span> <span class="info-label">体积利用率</span>
@@ -2310,12 +2328,23 @@ const ResultView = {
<span class="info-label">潜在焊缝线</span> <span class="info-label">潜在焊缝线</span>
<span class="info-value">{{ selectedKeyInfo.quality_considerations.potential_weld_lines || 0 }} 条</span> <span class="info-value">{{ selectedKeyInfo.quality_considerations.potential_weld_lines || 0 }} 条</span>
</div> </div>
<div class="recommendations-section" v-if="sortedRecommendations.length">
<h5>详细设计建议</h5>
<div class="recommendations-list">
<div v-for="rec in sortedRecommendations" :key="rec.type" class="recommendation-item" :class="rec.priority">
<span class="priority-badge" :class="rec.priority">{{ getPriorityText(rec.priority) }}</span>
<span class="recommendation-text">{{ rec.description }}</span>
<span class="recommendation-reason" v-if="rec.reason">({{ rec.reason }})</span>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<details class="viewer-section diagnostic-panel" v-if="stageTimingEntries.length || state.task.verification || state.task.llm_report"> <details id="diagnostic-info" class="viewer-section diagnostic-panel" v-if="stageTimingEntries.length || state.task.verification || state.task.llm_report">
<summary>诊断信息</summary> <summary>诊断信息</summary>
<div class="diagnostic-panel-body"> <div class="diagnostic-panel-body">
<div class="result-card full-width" v-if="stageTimingEntries.length"> <div class="result-card full-width" v-if="stageTimingEntries.length">