fix: 活跃作业从 DomainDetail 回退统计 + 修复 Gmail 嵌套 div 进度条

1. Z1 详细输出把作业存在 DomainDetail 而非 JobInfo, 增加回退逻辑
   按 (owner, pid, design) 去重统计活跃作业数
2. 移除利用率进度条的嵌套 div (Gmail 会过滤导致后续内容丢失)
   改为单元素蓝色进度条
3. 活跃作业卡片显示实际统计数而非 Snapshot 缓存值
This commit is contained in:
Your Name
2026-07-17 13:51:31 +08:00
parent c21f5028dd
commit 29ddfccc7b
+33 -8
View File
@@ -254,6 +254,35 @@ def collect_report_data() -> dict:
# ── 活跃作业 ──
jobs_active = JobInfo.query.filter_by(snapshot_id=latest.id).order_by(JobInfo.job_index).all()
# Z1 详细输出把作业信息存在 DomainDetail 里, 若 JobInfo 为空则从 DomainDetail 回退
if not jobs_active:
try:
from app import DomainDetail
domain_rows = DomainDetail.query.filter_by(snapshot_id=latest.id).all()
if domain_rows:
# 按 (owner, pid, design) 去重统计活跃作业数
active_set = set()
for dr in domain_rows:
owner = dr.owner or ""
pid = dr.pid or ""
if owner and owner not in ("NONE", "") and pid and pid not in ("0", ""):
active_set.add((owner, pid, dr.design or "", dr.t_pod or ""))
if active_set:
# 构造虚拟 job 对象供渲染 (兼容 jobs_active 格式)
class _VJob:
pass
for idx, (o, p, design, tpod) in enumerate(sorted(active_set), 1):
j = _VJob()
j.job_index = idx
j.owner = o
j.pid = p
j.t_pod = tpod
j.design = design
j.elap_time = ""
jobs_active.append(j)
except (ImportError, AttributeError):
pass
# ── 24h 统计 ──
snaps_24h = ScanSnapshot.query.filter(
ScanSnapshot.timestamp >= cutoff_24h
@@ -543,10 +572,8 @@ def _render_html(data: dict, base_url: str) -> str:
f'<tr><td style="padding:4px 12px;font-family:monospace">{_fmt_ts(smp.timestamp, "%m-%d %H:%M")}</td>'
f'<td style="padding:4px 12px;text-align:right;font-weight:bold">{smp.utilization:.1f}%</td>'
f'<td style="padding:4px 12px">'
f'<div style="background:#e0e0e0;height:14px;width:200px;border-radius:2px">'
f'<div style="background:{DOMAIN_COLORS.get("downloaded", "#007bff")};'
f'height:14px;width:{min(smp.utilization, 100):.1f}%;border-radius:2px"></div>'
f'</div></td></tr>'
f'<span style="background:#007bff;color:#fff;padding:2px 6px;border-radius:2px;font-size:11px;font-weight:bold">{smp.utilization:.1f}%</span>'
f'</td></tr>'
for smp in data["samples_24h"]
)
trend_html = f"""
@@ -607,14 +634,12 @@ def _render_html(data: dict, base_url: str) -> str:
<div style="flex:1;min-width:200px;background:#f8f9fa;padding:14px;border-radius:6px;border-left:4px solid {DOMAIN_COLORS.get('downloaded')}">
<div style="color:#888;font-size:12px">逻辑板利用率</div>
<div style="font-size:24px;font-weight:bold;margin-top:4px;color:#007bff">{latest.utilization:.1f}%</div>
<div style="background:#e0e0e0;height:8px;border-radius:4px;margin-top:6px">
<div style="background:{DOMAIN_COLORS.get('downloaded')};height:8px;width:{util_bar_width};border-radius:4px"></div>
</div>
<div style="background:#007bff;height:8px;border-radius:4px;margin-top:6px;width:{util_bar_width}"></div>
<div style="font-size:12px;margin-top:4px">使用 {latest.used_boards} / 空闲 {latest.online_boards - latest.used_boards}</div>
</div>
<div style="flex:1;min-width:140px;background:#f8f9fa;padding:14px;border-radius:6px;border-left:4px solid #28a745">
<div style="color:#888;font-size:12px">活跃作业</div>
<div style="font-size:24px;font-weight:bold;margin-top:4px">{latest.active_jobs}</div>
<div style="font-size:24px;font-weight:bold;margin-top:4px">{len(data.get('jobs_active', []))}</div>
</div>
</div>