/* ========================================================================= Screen 5: Result - 完成 + 下载 ========================================================================= */ import { state, resetState } from '../state.js'; import { downloadSignedFile } from '../api.js'; import { goStep, toast } from '../steps.js'; import { renderSummaryTo, showIntervalDialog } from './result-summary.js'; const STYLE_NAMES = { broker: '专业券商风', business: '商务风', minimal: '简洁风', chinese: '中国风', ink: '水墨风', }; function setPreview(index = 0) { const image = document.getElementById('resultPreviewImage'); const empty = document.getElementById('resultPreviewEmpty'); const badge = document.getElementById('resultPreviewBadge'); const urls = state.previewUrls || []; if (!image || !empty || !badge) return; if (!urls.length) { image.classList.add('hidden'); empty.classList.remove('hidden'); badge.classList.add('hidden'); return; } const safeIndex = Math.max(0, Math.min(index, urls.length - 1)); image.src = urls[safeIndex]; image.classList.remove('hidden'); empty.classList.add('hidden'); badge.textContent = `${String(safeIndex + 1).padStart(2, '0')} / ${String(state.slideCount || urls.length).padStart(2, '0')}`; badge.classList.remove('hidden'); } function renderThumbs() { const wrap = document.getElementById('resultThumbs'); if (!wrap) return; wrap.innerHTML = ''; const urls = state.previewUrls || []; if (!urls.length) return; urls.slice(0, 8).forEach((url, i) => { const btn = document.createElement('button'); btn.className = `result-thumb flex-shrink-0 w-24 aspect-video rounded-lg overflow-hidden border ${i === 0 ? 'border-2 border-primary-container' : 'border-border-subtle'} bg-surface-container-low shadow-sm`; btn.innerHTML = `第 ${i + 1} 页缩略图`; btn.onclick = () => { document.querySelectorAll('.result-thumb').forEach((x) => { x.classList.remove('border-2', 'border-primary-container'); x.classList.add('border', 'border-border-subtle'); }); btn.classList.remove('border', 'border-border-subtle'); btn.classList.add('border-2', 'border-primary-container'); setPreview(i); }; wrap.appendChild(btn); }); } function render() { const fnEl = document.getElementById('resultFilename'); if (fnEl) fnEl.textContent = state.resultFilename || 'plan.pptx'; const ext = (state.resultFilename || '').toLowerCase().endsWith('.pdf') ? 'PDF' : 'PPTX'; const styleName = STYLE_NAMES[state.selectedStyle] || '专业券商风'; const styleEl = document.getElementById('resultStyleName'); if (styleEl) styleEl.textContent = styleName; const summary = document.getElementById('resultSummary'); if (summary) { const products = (state.extractions || []).map(e => e.productName).filter(Boolean); summary.textContent = products.length > 0 ? `已为 ${products.join(' + ')} 联合定制方案` : '已为您生成定制方案'; } const metaValue = document.getElementById('resultMetaValue'); if (metaValue) { const kinds = [...new Set((state.extractions || []).map((e) => e.planType).filter(Boolean))]; metaValue.textContent = state.slideCount ? `${state.slideCount}页` : (kinds.length > 1 ? `${kinds.length}类产品` : '已完成'); } const mdBtn = document.getElementById('resultDownloadMdBtn'); if (mdBtn) mdBtn.style.display = state.markdownUrl ? 'flex' : 'none'; const downloadBtn = document.getElementById('resultDownloadBtn'); if (downloadBtn) { downloadBtn.innerHTML = `file_download 下载 .${ext}`; } renderThumbs(); setPreview(0); } async function downloadFile(url, filename, btnId) { if (!url) { toast('下载地址无效', 'error'); return; } const btn = document.getElementById(btnId); const oldHtml = btn ? btn.innerHTML : ''; if (btn) { btn.disabled = true; btn.innerHTML = 'progress_activity 准备下载...'; } try { const blob = await downloadSignedFile(url); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); URL.revokeObjectURL(a.href); toast('已开始下载', 'success'); if (btn) { btn.innerHTML = 'check_circle 已下载'; setTimeout(() => { btn.innerHTML = oldHtml; btn.disabled = false; }, 1800); } } catch (err) { toast('下载失败: ' + err.message, 'error'); if (btn) { btn.innerHTML = oldHtml; btn.disabled = false; } } } export function initResult() { render(); document.getElementById('resultDownloadBtn').onclick = () => { downloadFile(state.downloadUrl, state.resultFilename, 'resultDownloadBtn'); }; document.getElementById('resultDownloadMdBtn').onclick = () => { let fn = 'plan.md'; try { fn = decodeURIComponent(new URL(state.markdownUrl, location.origin).pathname.split('/').pop() || 'plan.md'); } catch {} downloadFile(state.markdownUrl, fn, 'resultDownloadMdBtn'); }; document.getElementById('resultNewBtn').onclick = () => { resetState(); goStep('upload'); }; const backChatBtn = document.getElementById('resultBackChatBtn'); if (backChatBtn) backChatBtn.onclick = () => { goStep('chat'); }; const regenBtn = document.getElementById('resultRegenerateBtn'); if (regenBtn) regenBtn.onclick = () => { goStep('generate'); }; // 仅储蓄险显示保单摘要图功能 const summaryBtn = document.getElementById('resultSummaryBtn'); if (summaryBtn) { const types = [...new Set((state.extractions || []).map(e => e.planType).filter(Boolean))]; if (types.length === 1 && types[0] === 'savings') { summaryBtn.style.display = 'flex'; summaryBtn.onclick = () => { showIntervalDialog(); }; } else { summaryBtn.style.display = 'none'; } } }