v1.7.0: 每日定时报告(工作日9:00盘前分析/15:30盘后总结) - 全球市场数据+报告引擎(简版邮件正文+详细版HTML附件)+cron定时+手动触发+发送日志; 修复模拟数据换手率失真

This commit is contained in:
2026-08-20 00:08:39 +08:00
parent 7d8ed3d7de
commit adc54d509f
8 changed files with 631 additions and 6 deletions
+29
View File
@@ -40,6 +40,34 @@ async function rebuildBt() {
} catch (e) { toast('启动失败'); }
}
/* 定时报告 */
async function sendReport(kind) {
const btn = event.target; btn.disabled = true;
try {
const r = await api('/api/report/send', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ kind }) });
toast(r.msg || '已启动');
setTimeout(loadReportLog, 60000);
setTimeout(loadReportLog, 150000);
} catch (e) { toast('启动失败:' + e.message); }
btn.disabled = false;
}
async function loadReportLog() {
try {
const d = await api('/api/report/log');
const items = d.items || [];
if (!items.length) return;
$('#reportLogTb').innerHTML = items.map(r => `
<tr>
<td style="color:var(--muted)">${r.sent_at}</td>
<td>${r.kind === 'premarket' ? '🌅 盘前' : '🌇 盘后'}</td>
<td>${escapeHtml(r.subject)}</td>
<td><span class="tag ${r.status === 'sent' ? 'tag-推荐' : 'tag-负'}">${r.status}</span></td>
<td style="color:var(--text2);font-size:12px">${escapeHtml(r.message || '')}</td>
</tr>`).join('');
} catch (e) {}
}
async function reseed() {
if (!confirm('将清空全部业务数据并重新生成(含向量索引重建,需 1-3 分钟),确定继续?')) return;
try {
@@ -67,3 +95,4 @@ async function health() {
}
refreshStats();
loadReportLog();