diff --git a/static/style.css b/static/style.css index 963f955..8149276 100644 --- a/static/style.css +++ b/static/style.css @@ -1348,6 +1348,51 @@ optgroup { background: linear-gradient(180deg, var(--bg-primary) 0%, var(--primary-50) 100%); } +.mechanism-list { + display: flex; + flex-direction: column; + gap: var(--space-4); +} + +.mechanism-card { + border: 1px solid var(--border-light); + border-radius: var(--radius-lg); + padding: var(--space-4); + background: var(--bg-primary); +} + +.mechanism-title { + font-size: var(--text-base); + font-weight: var(--font-semibold); + color: var(--text-primary); + margin-bottom: var(--space-3); +} + +.mechanism-subtitle { + font-size: var(--text-sm); + font-weight: var(--font-semibold); + color: var(--text-secondary); + margin-bottom: var(--space-2); +} + +.mechanism-notes { + margin-top: var(--space-4); + padding-top: var(--space-4); + border-top: 1px solid var(--border-light); +} + +.mechanism-note-list { + margin: 0; + padding-left: 1.1rem; + color: var(--text-secondary); + font-size: var(--text-sm); + line-height: 1.7; +} + +.mechanism-note-list li + li { + margin-top: var(--space-2); +} + .result-priority-grid { margin-bottom: var(--space-6); } diff --git a/static/vue-app.js b/static/vue-app.js index 6909396..726d294 100644 --- a/static/vue-app.js +++ b/static/vue-app.js @@ -1509,6 +1509,16 @@ const ResultView = { const selectedHtmlFile = computed(() => selectedScheme.value?.html_file || state.task?.html_file || ''); const selectedDfmViolations = computed(() => selectedScheme.value?.dfm_violations || []); const selectedInjectionSystem = computed(() => selectedCavityData.value?.injection_system || state.task?.plan_result?.injection_system || null); + const selectedSideActions = computed(() => { + return selectedScheme.value?.side_actions + || selectedCavityData.value?.side_actions + || state.task?.side_actions + || null; + }); + const sideActionSummary = computed(() => selectedSideActions.value?.summary || {}); + const sliderMechanisms = computed(() => selectedSideActions.value?.slider_mechanisms || []); + const lifterMechanisms = computed(() => selectedSideActions.value?.lifter_mechanisms || []); + const sideActionRecommendations = computed(() => selectedSideActions.value?.recommendations || []); const stageTimingEntries = computed(() => { const timings = state.task?.stage_timings || {}; return Object.entries(timings) @@ -1538,6 +1548,7 @@ const ResultView = { const resultAnchorLinks = [ { id: 'candidate-schemes', label: '方案' }, { id: 'engineering-summary', label: '工程摘要' }, + { id: 'side-actions', label: '抽芯建议' }, { id: 'dfm-check', label: 'DFM' }, { id: 'preview-3d', label: '预览' }, { id: 'export-cam', label: '导出/CAM' }, @@ -1601,6 +1612,15 @@ const ResultView = { return stageNameMap[name] || name; }; const formatTiming = (value) => `${Number(value || 0).toFixed(3)} s`; + const formatVector = (vector) => { + if (!Array.isArray(vector)) return 'N/A'; + return `[${vector.map(v => Number(v).toFixed(2)).join(', ')}]`; + }; + const formatMechanismSize = (size) => { + if (!size || typeof size !== 'object') return 'N/A'; + const keys = Object.keys(size); + return keys.map(key => `${key}:${Number(size[key]).toFixed(1)} mm`).join(' / '); + }; const exportCAD = async (format) => { try { @@ -1695,12 +1715,19 @@ const ResultView = { selectedHtmlFile, selectedDfmViolations, selectedInjectionSystem, + selectedSideActions, + sideActionSummary, + sliderMechanisms, + lifterMechanisms, + sideActionRecommendations, stageTimingEntries, getWallThicknessSummary, countFeaturesByTypes, getUndercutCount, formatStageName, formatTiming, + formatVector, + formatMechanismSize, primaryRecommendation, sortedRecommendations, selectedDfmCount, @@ -2062,6 +2089,140 @@ const ResultView = { +