feat: 四份报告按用户口径重做

- 核验日报: 先报订单数量(远程vs本地, verify 修复后重数 verifyReport.post)/商品行数一致性, 再报状态不符单数; SDS 统计口径排除'售后'与本地对称
- OCR: Orders 加 ocrProcessedAt 列(写入自动盖时间戳), 日报报'今日处理 X · 识别失败 Y'(db.count_ocr_today)
- 失败任务: check_prefect_failures 补 workflow 名, 日报/设备报列 run 名+状态+时间
- 设备日报: 新增 metrics-agent 侧车(每5分钟采样内存/swap/GPU+每日 du 快照), 报告改 平均/峰值/最低 + 总体/根目录/home 余量 + 增长最快目录 + GPU 温度; 采样缺失降级瞬时值
- Dockerfile 加 tzdata(TZ=Asia/Shanghai); du 用实际占块且容错 rc=1
This commit is contained in:
yeuimu
2026-08-28 05:01:55 +00:00
parent 66db7b279d
commit 7c323e9a3f
11 changed files with 601 additions and 108 deletions
+18 -1
View File
@@ -200,9 +200,10 @@ class SyncDB:
def update_ocr_fields(
self, order_no: str, created_at: datetime, fields: dict[str, str | None]
) -> None:
"""更新单个订单的 ocr_* 字段。fields 为 {ocr_xxx: value} 字典。"""
"""更新单个订单的 ocr_* 字段。fields 为 {ocr_xxx: value} 字典。自动盖处理时间戳。"""
if not fields:
return
fields = {"ocrProcessedAt": datetime.now(), **fields}
assignments = ", ".join(f'"{k}"=%s' for k in fields)
params = list(fields.values()) + [order_no, created_at]
with self._conn() as conn:
@@ -228,6 +229,7 @@ class SyncDB:
for order_no, created_at, fields in updates:
if not fields:
continue
fields = {"ocrProcessedAt": datetime.now(), **fields}
assignments = ", ".join(f'"{k}"=%s' for k in fields)
params = list(fields.values()) + [order_no, created_at]
cur.execute(
@@ -258,6 +260,21 @@ class SyncDB:
row = cur.fetchone()
return {"done": row[0], "error": row[1], "unsupported": row[2], "pending": row[3]} if row else {}
def count_ocr_today(self, day_start: datetime) -> dict[str, int]:
"""今日 OCR 处理量(按 ocrProcessedAt 盖章时间):processed=成功识别, failed=识别失败/不支持。"""
with self._conn() as conn:
with conn.cursor() as cur:
cur.execute(
'''SELECT
COUNT(*) FILTER (WHERE "ocrLayout" IS NOT NULL
AND "ocrLayout" NOT IN ('ERROR','UNSUPPORTED')) AS processed,
COUNT(*) FILTER (WHERE "ocrLayout" IN ('ERROR','UNSUPPORTED')) AS failed
FROM "Orders" WHERE "ocrProcessedAt">=%s''',
(day_start,),
)
row = cur.fetchone()
return {"processed": row[0], "failed": row[1]} if row else {"processed": 0, "failed": 0}
# ---------- 主 upsert ----------
def sync_orders_and_goods(