合入小程序修改,新增告警功能
This commit is contained in:
129
talkingq-url/services/device_identity_initializer.py
Normal file
129
talkingq-url/services/device_identity_initializer.py
Normal file
@@ -0,0 +1,129 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from sqlalchemy import text
|
||||
|
||||
from services.database_service_base import DatabaseServiceBase
|
||||
from utils.logger import session_logger
|
||||
|
||||
|
||||
class DeviceIdentityInitializationError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DeviceIdentityInitializationResult:
|
||||
imei: str
|
||||
device_id: str
|
||||
serial_number: str
|
||||
activated: bool
|
||||
|
||||
|
||||
class DeviceIdentityInitializer(DatabaseServiceBase):
|
||||
def __init__(self):
|
||||
super().__init__(service_name="device_identity_initializer")
|
||||
|
||||
async def initialize_by_imei(self, imei: str) -> DeviceIdentityInitializationResult:
|
||||
normalized_imei = str(imei or "").strip()
|
||||
if not normalized_imei:
|
||||
raise DeviceIdentityInitializationError("imei is required")
|
||||
|
||||
db_session = await self.get_session()
|
||||
try:
|
||||
mapping_result = await db_session.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT imei, device_id, serial_number, status
|
||||
FROM device_imei_mapping
|
||||
WHERE imei = :imei
|
||||
LIMIT 1
|
||||
"""
|
||||
),
|
||||
{"imei": normalized_imei},
|
||||
)
|
||||
mapping = mapping_result.mappings().first()
|
||||
if mapping is None:
|
||||
raise DeviceIdentityInitializationError("imei mapping not found")
|
||||
|
||||
device_id = str(mapping["device_id"]).strip()
|
||||
serial_number = str(mapping["serial_number"]).strip()
|
||||
if not device_id or not serial_number:
|
||||
raise DeviceIdentityInitializationError("imei mapping is incomplete")
|
||||
|
||||
device_auth_result = await db_session.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT device_id, serial_number
|
||||
FROM device_auth
|
||||
WHERE device_id = :device_id
|
||||
LIMIT 1
|
||||
"""
|
||||
),
|
||||
{"device_id": device_id},
|
||||
)
|
||||
device_auth = device_auth_result.mappings().first()
|
||||
if device_auth is None:
|
||||
await db_session.execute(
|
||||
text(
|
||||
"""
|
||||
INSERT INTO device_auth (device_id, serial_number, is_active)
|
||||
VALUES (:device_id, :serial_number, 1)
|
||||
"""
|
||||
),
|
||||
{"device_id": device_id, "serial_number": serial_number},
|
||||
)
|
||||
elif str(device_auth["serial_number"]) != serial_number:
|
||||
raise DeviceIdentityInitializationError("device_auth serial_number conflict")
|
||||
else:
|
||||
await db_session.execute(
|
||||
text(
|
||||
"""
|
||||
UPDATE device_auth
|
||||
SET is_active = 1
|
||||
WHERE device_id = :device_id
|
||||
"""
|
||||
),
|
||||
{"device_id": device_id},
|
||||
)
|
||||
|
||||
await db_session.execute(
|
||||
text(
|
||||
"""
|
||||
UPDATE device_imei_mapping
|
||||
SET status = 'activated',
|
||||
activated_at = COALESCE(activated_at, CURRENT_TIMESTAMP)
|
||||
WHERE imei = :imei
|
||||
"""
|
||||
),
|
||||
{"imei": normalized_imei},
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
session_logger.info(
|
||||
device_id,
|
||||
"device_identity_initializer",
|
||||
f"IMEI identity initialized: imei={normalized_imei}",
|
||||
)
|
||||
return DeviceIdentityInitializationResult(
|
||||
imei=normalized_imei,
|
||||
device_id=device_id,
|
||||
serial_number=serial_number,
|
||||
activated=str(mapping["status"]) == "activated",
|
||||
)
|
||||
except DeviceIdentityInitializationError:
|
||||
await db_session.rollback()
|
||||
raise
|
||||
except Exception as exc:
|
||||
await db_session.rollback()
|
||||
session_logger.error(
|
||||
normalized_imei,
|
||||
"device_identity_initializer",
|
||||
f"initialize identity failed: {exc}",
|
||||
)
|
||||
raise
|
||||
finally:
|
||||
await db_session.close()
|
||||
|
||||
|
||||
device_identity_initializer = DeviceIdentityInitializer()
|
||||
Reference in New Issue
Block a user