Commit Graph

2 Commits

Author SHA1 Message Date
DXC
783c633a15 feat: 时效判定结构化下沉到后端,修复状态映射漏掉 offline
背景:此前「滞后几天」在后端(calculate_offset)和前端(Dashboard.vue 自算
diffDays/diffHours)各有一套实现,阈值与粒度都不同,跨日必然打架 —— 昨天
23:00 的数据在次日 01:00 查看,后端说「滞后 1 天」,前端标「昨日数据」。

services/time_utils.py:
- 新增 staleness_of(),统一返回 {level, days, text},level 分
  unknown / ok / yesterday / lagging / severe 五级。
- 日期解析改用正则抠 YYYY-MM-DD,分隔符兼容 - / _,因此 ISO 的
  2026-09-15T08:30:00Z、2026/09/15、2026_09_15 都能识别。
  原来的 split(' ')[0] + strptime('%Y-%m-%d') 遇到 ISO T 或斜杠会直接返回
  「时间解析失败」,而 82 爬虫的 target_time 是原样透传接口返回值的,格式
  不可控。
- calculate_offset 保留为兼容入口,内部委托 staleness_of。

models.py:
- to_dict() 新增 stale_level / stale_days。
- 修复状态映射:白名单原来只有 ['离线','异常','已离线'],漏了 'offline',
  而 /add_device 创建手动设备写的正是 status='offline',导致手动添加的设备
  被映射成 online、在面板上永远显示「在线」。改为大小写归一后比对,并纳入
  unknown/未知。

实测:本地库 status 分布由 online:103/offline:2 修正为 online:99/offline:6。
2026-09-15 17:10:53 +08:00
DXC
d66e2826e1 refactor: 抽出统一入库管道,合并定时与手动两条重复路径
问题:app.py:auto_monitor_job(定时)和 routes/api.py:run_monitor(手动)
各自维护了一份几乎相同但细节不一致的写入逻辑,同一条数据经不同入口落库后
latest_time / source / offset / file_count 可能不同。

- 新增 services/time_utils.py:calculate_offset 下沉到无依赖模块,避免
  db_ingest 与 routes.api 互相 import 形成循环。routes/api.py 里 re-export
  一次,保证 app.py 原有的 from routes.api import calculate_offset 不失效。
- 新增 services/db_ingest.py:ingest_device_data(),承载全部入库细节,只
  add/flush 不 commit,事务边界交给调用方。
- routes/api.py:run_monitor 瘦身为「触发爬虫 -> 调管道 -> 提交」。
- models.py:to_dict() 的 offset 改为读取时用 calculate_offset(latest_time)
  实时计算,不再读 offset 列。该列是写入时刻的快照,采集一停摆就整体失真
  (库里停在 2026-02-06,offset 却仍显示“当天”)。列保留但已废弃,
  不执行 ALTER TABLE DROP COLUMN。

入库语义(db_ingest):
- 只有爬虫拿到真实业务时间才更新主表 latest_time,拿不到就保留上一个有效值
  (冻结),不再回退到 current_time。
- DeviceHistory 单独用 history_time:主表回答“数据到什么时候”,历史回答
  “什么时候采过”。
- 历史表 json_data 改存本次增量切片,不再复制主表那份越滚越大的累积 JSON。
- 主表 json_data 改为覆盖式更新以切断无限膨胀,但保留 APP_OWNED_KEYS
  (bound_iccid / is_whitelist)—— 这两个键由 /bind_device_card 和
  /toggle_whitelist 写入,按原方案直接覆盖会清空所有设备-流量卡绑定。
2026-09-15 17:05:38 +08:00