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('')}${tag}>`;
}
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;
}
});