fix: 统一所有服务时间为北京时间 + 处理/忽略时计算告警时长

- notify_dispatch: _mark_false_alarm 使用 beijing_now() + 计算 duration_ms
- alarm_event_service: handle_alarm 处理时自动计算 duration_ms 和 last_frame_time
- notification_service: datetime.utcnow() 替换为 beijing_now()
- device_service: datetime.now(timezone.utc) 替换为 beijing_now()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 16:27:30 +08:00
parent 1585abf843
commit 766ee6a69a
4 changed files with 37 additions and 10 deletions

View File

@@ -415,8 +415,22 @@ class AlarmEventService:
alarm.handle_remark = remark alarm.handle_remark = remark
if handler: if handler:
alarm.handler = handler alarm.handler = handler
alarm.handled_at = beijing_now()
alarm.updated_at = beijing_now() now = beijing_now()
alarm.handled_at = now
alarm.updated_at = now
# 如果没有 duration_ms 且有 event_time计算告警时长
if alarm.duration_ms is None and alarm.event_time:
try:
delta = now - alarm.event_time
alarm.duration_ms = int(delta.total_seconds() * 1000)
except Exception:
pass
# 如果没有 last_frame_time设置为当前处理时间
if alarm.last_frame_time is None:
alarm.last_frame_time = now
db.commit() db.commit()
db.refresh(alarm) db.refresh(alarm)

View File

@@ -7,6 +7,7 @@ from typing import Dict, Any, List, Optional
from app.models import EdgeDevice, DeviceStatus, get_session from app.models import EdgeDevice, DeviceStatus, get_session
from app.utils.logger import logger from app.utils.logger import logger
from app.utils.timezone import beijing_now
class DeviceService: class DeviceService:
@@ -32,7 +33,7 @@ class DeviceService:
"""检查离线设备""" """检查离线设备"""
db = get_session() db = get_session()
try: try:
threshold = datetime.now(timezone.utc) - timedelta(seconds=self.OFFLINE_TIMEOUT) threshold = beijing_now() - timedelta(seconds=self.OFFLINE_TIMEOUT)
# 查找需要标记为离线的设备 # 查找需要标记为离线的设备
devices = db.query(EdgeDevice).filter( devices = db.query(EdgeDevice).filter(
@@ -43,7 +44,7 @@ class DeviceService:
offline_devices = [] offline_devices = []
for device in devices: for device in devices:
device.status = DeviceStatus.OFFLINE device.status = DeviceStatus.OFFLINE
device.updated_at = datetime.now(timezone.utc) device.updated_at = beijing_now()
offline_devices.append(device) offline_devices.append(device)
logger.info(f"设备离线: {device.device_id}") logger.info(f"设备离线: {device.device_id}")

View File

@@ -9,6 +9,7 @@ from typing import Dict, Any, List, Set
from fastapi import WebSocket from fastapi import WebSocket
from app.utils.logger import logger from app.utils.logger import logger
from app.utils.timezone import beijing_now
class ConnectionManager: class ConnectionManager:
@@ -80,7 +81,7 @@ class NotificationService:
message = { message = {
"event": "new_alert", "event": "new_alert",
"data": alert_data, "data": alert_data,
"timestamp": datetime.utcnow().isoformat(), "timestamp": beijing_now().isoformat(),
} }
await self._manager.broadcast(message) await self._manager.broadcast(message)
logger.debug(f"已广播新告警通知: {alert_data.get('alert_no', 'N/A')}") logger.debug(f"已广播新告警通知: {alert_data.get('alert_no', 'N/A')}")
@@ -90,7 +91,7 @@ class NotificationService:
message = { message = {
"event": "alert_updated", "event": "alert_updated",
"data": alert_data, "data": alert_data,
"timestamp": datetime.utcnow().isoformat(), "timestamp": beijing_now().isoformat(),
} }
await self._manager.broadcast(message) await self._manager.broadcast(message)
@@ -99,7 +100,7 @@ class NotificationService:
message = { message = {
"event": "device_status", "event": "device_status",
"data": device_data, "data": device_data,
"timestamp": datetime.utcnow().isoformat(), "timestamp": beijing_now().isoformat(),
} }
await self._manager.broadcast(message) await self._manager.broadcast(message)
@@ -108,7 +109,7 @@ class NotificationService:
message = { message = {
"event": f"work_order_{event_type}", "event": f"work_order_{event_type}",
"data": order_data, "data": order_data,
"timestamp": datetime.utcnow().isoformat(), "timestamp": beijing_now().isoformat(),
} }
await self._manager.broadcast(message) await self._manager.broadcast(message)
@@ -121,7 +122,7 @@ class NotificationService:
message = { message = {
"event": event, "event": event,
"data": data, "data": data,
"timestamp": datetime.utcnow().isoformat(), "timestamp": beijing_now().isoformat(),
} }
async def _broadcast(): async def _broadcast():

View File

@@ -22,6 +22,7 @@ from app.config import settings
from app.services.vlm_service import get_vlm_service from app.services.vlm_service import get_vlm_service
from app.services.wechat_service import get_wechat_service from app.services.wechat_service import get_wechat_service
from app.utils.logger import logger from app.utils.logger import logger
from app.utils.timezone import beijing_now
async def process_alarm_notification(alarm_data: Dict): async def process_alarm_notification(alarm_data: Dict):
@@ -151,10 +152,20 @@ def _mark_false_alarm(alarm_id: str):
try: try:
alarm = db.query(AlarmEvent).filter(AlarmEvent.alarm_id == alarm_id).first() alarm = db.query(AlarmEvent).filter(AlarmEvent.alarm_id == alarm_id).first()
if alarm: if alarm:
now = beijing_now()
alarm.alarm_status = "FALSE" alarm.alarm_status = "FALSE"
alarm.handle_status = "DONE" alarm.handle_status = "DONE"
alarm.handle_remark = "VLM复核判定误报" alarm.handle_remark = "VLM复核判定误报"
alarm.handled_at = datetime.now() alarm.handled_at = now
# 计算告警时长VLM复核时间 - 事件时间)
if alarm.duration_ms is None and alarm.event_time:
try:
delta = now - alarm.event_time
alarm.duration_ms = int(delta.total_seconds() * 1000)
except Exception:
pass
if alarm.last_frame_time is None:
alarm.last_frame_time = now
db.commit() db.commit()
logger.info(f"告警已标记误报: {alarm_id}") logger.info(f"告警已标记误报: {alarm_id}")
except Exception as e: except Exception as e: