sage/wwwroot/hotspot/index.ui
yumoqing 64cc51cb6e feat(hotspot): comprehensive revamp — 6 tables, 3 fetch modes, 5-dim analysis
Database (3→6 tables):
- hotspot_source: support api/browser/crawler types with type-specific fields
- hotspot_schedule: cron/interval daemon config per source
- hotspot_fetch_log: per-run audit trail (status/duration/items/errors)
- hotspot_item: add heat_velocity, engagement/comment/share counts, sentiment
- hotspot_analysis: 5-dimension scoring (time/heat/content/propagation/audience)
- hotspot_alert: alert rules (heat threshold/velocity/sentiment triggers)

Fetch engine (3 modes):
- API: GET/POST + headers + Bearer auth + JSON extraction
- Browser: HTML title/link extraction + og:title fallback
- Crawler: recursive with depth/domain allowlist/link following

Analysis engine:
- Exponential decay model (7-day half-life)
- Auto-classify: emerging→rising→hot→cooling→expired
- 5-dimension scoring with detail JSON per dimension

Dashboard: 6 tabs + 7 stat cards + workflow guide
Permission paths: 42 paths registered (6 tables × 7 CRUD ops)
2026-08-01 11:14:58 +08:00

183 lines
10 KiB
XML

{% set roles = get_user_roles(get_user()) %}
{
"widgettype": "VBox",
"options": {
"children": [
{
"widgettype": "HBox",
"options": {
"children": [
{
"widgettype": "VBox",
"options": {
"id": "stat_emerging",
"children": [
{"widgettype": "Text", "options": {"text": "潜在热点", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#52c41a;"}}
],
"style": "padding:14px;background:#f6ffed;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #b7eb8f;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_rising",
"children": [
{"widgettype": "Text", "options": {"text": "上升中", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#1890ff;"}}
],
"style": "padding:14px;background:#e6f7ff;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #91d5ff;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_hot",
"children": [
{"widgettype": "Text", "options": {"text": "正热点", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#ff4d4f;"}}
],
"style": "padding:14px;background:#fff1f0;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #ffa39e;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_cooling",
"children": [
{"widgettype": "Text", "options": {"text": "降温中", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#faad14;"}}
],
"style": "padding:14px;background:#fffbe6;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #ffe58f;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_expired",
"children": [
{"widgettype": "Text", "options": {"text": "已过期", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#bfbfbf;"}}
],
"style": "padding:14px;background:#fafafa;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #d9d9d9;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_sources",
"children": [
{"widgettype": "Text", "options": {"text": "活跃来源", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#722ed1;"}}
],
"style": "padding:14px;background:#f9f0ff;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #d3adf7;"
}
},
{
"widgettype": "VBox",
"options": {
"id": "stat_failures",
"children": [
{"widgettype": "Text", "options": {"text": "24h 抓取失败", "style": "color:#666;font-size:12px;"}},
{"widgettype": "Text", "options": {"text": "0", "style": "font-size:32px;font-weight:bold;color:#ff7875;"}}
],
"style": "padding:14px;background:#fff2f0;border-radius:8px;margin:6px;min-width:90px;text-align:center;border:1px solid #ffccc7;"
}
}
]
}
},
{
"widgettype": "HBox",
"options": {
"children": [
{
"widgettype": "Button",
"options": {
"label": "立即抓取全部来源",
"actiontype": "script",
"script": "fetch('/hotspot/fetch_now.dspy').then(r=>r.json()).then(d=>{var m='完成: '+d.total+'来源, 新增'+d.new_items+'条';if(d.errors)m+='\\\\n失败: '+d.errors;alert(m);setTimeout(()=>location.reload(),1000);}).catch(e=>alert('异常: '+e))",
"style": "margin:6px;"
}
},
{
"widgettype": "Button",
"options": {
"label": "执行分析",
"actiontype": "script",
"script": "fetch('/hotspot/analyze.dspy').then(r=>r.json()).then(d=>{alert('已分析: '+d.analyzed+'条热点');setTimeout(()=>location.reload(),1000);}).catch(e=>alert('分析异常: '+e))",
"style": "margin:6px;"
}
},
{
"widgettype": "Button",
"options": {
"label": "刷新统计",
"actiontype": "script",
"script": "fetch('/hotspot/stats.dspy').then(r=>r.json()).then(d=>{['emerging','rising','hot','cooling','expired','sources','failures'].forEach(k=>{var el=document.querySelectorAll('[id=stat_'+k+'] div')[1];if(el)el.textContent=d[k]||0;});}).catch(e=>console.error('stats err',e))",
"style": "margin:6px;"
}
}
]
}
},
{
"widgettype": "Tab",
"options": {
"tabs": [
{
"title": "来源管理",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_source') }}"}
}
},
{
"title": "调度配置",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_schedule') }}"}
}
},
{
"title": "抓取日志",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_fetch_log') }}"}
}
},
{
"title": "热点条目",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_item') }}"}
}
},
{
"title": "五维分析",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_analysis') }}"}
}
},
{
"title": "预警规则",
"content": {
"widgettype": "urlwidget",
"options": {"url": "{{ entire_url('hotspot_alert') }}"}
}
}
]
}
},
{
"widgettype": "Text",
"options": {
"text": "工作流: ① 添加来源(type=api/browser/crawler) → ② 配置调度(cron/interval) → ③ 查看抓取日志(成功率/错误) → ④ 浏览热点(emerging/rising/hot/cooling/expired) → ⑤ 五维分析 → ⑥ 设置预警",
"style": "font-size:12px;color:#bbb;padding:16px;border-top:1px solid #eee;margin-top:8px;"
}
}
]
}
}