初始化红餐观察库项目
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
.article-card > p.ai-summary {
|
||||
color: #3f3e3a;
|
||||
}
|
||||
|
||||
.ai-summary b {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
color: var(--accent);
|
||||
font: 700 9px/1 ui-monospace, monospace;
|
||||
letter-spacing: .08em;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,45 @@
|
||||
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 => `<li>${escapeHtml(x)}</li>`).join('')}</${tag}>`;
|
||||
}
|
||||
|
||||
function renderAnalysis(a) {
|
||||
return `
|
||||
<section><h3>一句话摘要</h3><p>${escapeHtml(a.summary)}</p></section>
|
||||
<section><h3>核心要点</h3>${renderList(a.key_points)}</section>
|
||||
<section><h3>行业信号</h3><p>${escapeHtml(a.industry_signal)}</p></section>
|
||||
<section><h3>关键数据</h3>${renderList(a.numbers)}</section>
|
||||
<section><h3>延展选题</h3>${renderList(a.content_angles, true)}</section>
|
||||
<section><h3>风险提示</h3>${renderList(a.risk_notes)}</section>
|
||||
<section><h3>标签</h3><div class="tags">${(a.tags || []).map(x => `<span>${escapeHtml(x)}</span>`).join('')}</div></section>`;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.signals-block{padding:68px 0;border-bottom:1px solid var(--line)}.signals-title{display:flex;justify-content:space-between;align-items:end;margin-bottom:25px}.signals-title h2{margin:0;font-size:32px;letter-spacing:-.04em}.signals-title p,.signals-title time{margin:8px 0 0;color:var(--muted);font-size:12px}.signal-grid{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--ink)}.signal-card{min-height:300px;padding:22px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}.signal-card:nth-child(4n){border-right:0}.signal-card>div:first-child{display:flex;justify-content:space-between;align-items:center}.signal-card strong{font:11px ui-monospace,monospace;color:var(--muted)}.trend{display:inline-block;padding:5px 8px;border-radius:999px;background:var(--ink);color:white;font:700 9px ui-monospace,monospace;letter-spacing:.06em}.trend-加速{background:var(--accent)}.trend-新兴{background:#2b8a6f}.trend-稳定{background:#4a6fa5}.trend-下行{background:#888}.signal-card h3{margin:28px 0 14px;font-size:21px;line-height:1.3}.signal-card>p{color:var(--muted);font-size:13px;line-height:1.7}.signal-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:20px}.signal-tags span{font-size:10px;padding:4px 8px;border-radius:999px;background:rgba(216,73,47,.08);color:var(--accent);border:1px solid rgba(216,73,47,.15)}.signal-page{max-width:900px;padding:60px 0 100px}.signal-page header>p{color:var(--muted);font-size:12px}.signal-page h1{margin:22px 0;font-size:clamp(42px,6vw,76px);line-height:1.05;letter-spacing:-.055em}.signal-lead{font-size:20px;line-height:1.8;color:#454440}.signal-page section{margin-top:60px;border-top:1px solid var(--ink);padding-top:22px}.signal-page section h2{font-size:18px}.signal-page li{margin-bottom:14px;line-height:1.7}.evidence{display:grid;grid-template-columns:160px 1fr;gap:20px;padding:16px 0;border-bottom:1px solid var(--line)}.evidence time{color:var(--muted);font:11px ui-monospace,monospace}.evidence span{font-size:15px}.signal-page>.tags{margin-top:40px}@media(max-width:960px){.signal-grid{grid-template-columns:repeat(2,1fr)}.signal-card:nth-child(n){border-right:1px solid var(--line)}.signal-card:nth-child(even){border-right:0}}@media(max-width:640px){.signals-block{padding:44px 0}.signals-title{display:block;margin-bottom:18px}.signals-title h2{font-size:24px}.signals-title p,.signals-title time{font-size:11px;margin-top:6px}.signal-grid{grid-template-columns:1fr}.signal-card{min-height:auto;padding:20px 0;border-right:0}.signal-card h3{margin:20px 0 12px;font-size:19px;line-height:1.35}.signal-card>p{font-size:13px;line-height:1.65}.signal-tags{margin-top:16px}.signal-tags span{font-size:10px}.signal-page{padding:36px 0 50px}.signal-page header>p{font-size:11px}.signal-page h1{margin:18px 0;font-size:30px;line-height:1.12;letter-spacing:-.03em}.signal-lead{font-size:17px;line-height:1.7}.signal-page section{margin-top:40px;padding-top:18px}.signal-page section h2{font-size:16px}.signal-page li{margin-bottom:12px;line-height:1.65;font-size:15px}.evidence{grid-template-columns:1fr;gap:4px;padding:14px 0}.evidence time{font-size:10px}.evidence span{font-size:14px}.signal-page>.tags{margin-top:30px}}@media(max-width:480px){.signals-title h2{font-size:22px}.signal-card h3{font-size:18px}.signal-page h1{font-size:26px}.signal-lead{font-size:16px}}
|
||||
Reference in New Issue
Block a user