const button = document.querySelector('#analyzeBtn'); const statusBox = document.querySelector('#analysisStatus'); const content = document.querySelector('#analysisContent'); const escapeHtml = (value = '') => String(value).replace(/[&<>'"]/g, c => ({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c])); function renderList(items, ordered = false) { const tag = ordered ? 'ol' : 'ul'; return `<${tag}>${(items || []).map(x => `
  • ${escapeHtml(x)}
  • `).join('')}`; } function renderAnalysis(a) { return `

    一句话摘要

    ${escapeHtml(a.summary)}

    核心要点

    ${renderList(a.key_points)}

    行业信号

    ${escapeHtml(a.industry_signal)}

    关键数据

    ${renderList(a.numbers)}

    延展选题

    ${renderList(a.content_angles, true)}

    风险提示

    ${renderList(a.risk_notes)}

    标签

    ${(a.tags || []).map(x => `${escapeHtml(x)}`).join('')}
    `; } button?.addEventListener('click', async () => { button.disabled = true; statusBox.hidden = false; statusBox.className = 'analysis-status loading'; statusBox.textContent = '千问正在阅读全文并提炼行业信号…'; try { const response = await fetch(`/api/articles/${button.dataset.id}/analyze`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({force: button.textContent.includes('重新')}) }); const data = await response.json(); if (!data.ok) throw new Error(data.error || '分析失败'); content.innerHTML = renderAnalysis(data.analysis); statusBox.className = 'analysis-status success'; statusBox.textContent = data.cached ? '已载入缓存分析' : '分析完成并已保存'; button.textContent = '重新分析'; } catch (error) { statusBox.className = 'analysis-status error'; statusBox.textContent = error.message; } finally { button.disabled = false; } });