feat: 性能优化 + 设备总览轨迹展示 + 广播指令API

性能: SQLite WAL模式、aiohttp Session复用、TCP连接锁+空闲超时、
device_id缓存、WebSocket并发广播、API Key认证缓存、围栏N+1查询
批量化、逆地理编码并行化、新增5个DB索引、日志降级DEBUG

功能: 广播指令API(broadcast)、exclude_type低精度后端过滤、
前端设备总览Tab+多设备轨迹叠加+高亮联动+搜索+专属颜色

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
2026-03-31 09:41:09 +00:00
parent b970b78136
commit b25eafc483
12 changed files with 1030 additions and 244 deletions

View File

@@ -15,6 +15,7 @@ async def get_locations(
db: AsyncSession,
device_id: int | None = None,
location_type: str | None = None,
exclude_type: str | None = None,
start_time: datetime | None = None,
end_time: datetime | None = None,
page: int = 1,
@@ -56,6 +57,14 @@ async def get_locations(
query = query.where(LocationRecord.location_type == location_type)
count_query = count_query.where(LocationRecord.location_type == location_type)
if exclude_type:
# Map prefix to actual values for index-friendly IN query
_EXCLUDE_MAP = {"lbs": ["lbs", "lbs_4g"], "wifi": ["wifi", "wifi_4g"], "gps": ["gps", "gps_4g"]}
exclude_values = _EXCLUDE_MAP.get(exclude_type, [exclude_type])
clause = LocationRecord.location_type.notin_(exclude_values)
query = query.where(clause)
count_query = count_query.where(clause)
if start_time:
query = query.where(LocationRecord.recorded_at >= start_time)
count_query = count_query.where(LocationRecord.recorded_at >= start_time)