feat: 围栏Tab布局重构、低精度过滤、蓝牙考勤去重、考勤删除API
- 围栏管理页面Tab移至顶部,设备绑定Tab隐藏地图全屏展示绑定矩阵 - 位置追踪新增"低精度"按钮,隐藏LBS/WiFi点(地图+折线+表格联动) - 移除LBS/WiFi精度半径圆圈,仅通过标记颜色区分定位类型 - 蓝牙打卡(0xB2)自动创建考勤记录,含去重和WebSocket广播 - 新增考勤批量删除和单条删除API - fence_checker补充json导入 via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
@@ -2064,12 +2064,53 @@ class TCPManager:
|
||||
beacon_major, beacon_minor, rssi,
|
||||
beacon_battery or 0,
|
||||
)
|
||||
|
||||
# Create AttendanceRecord for bluetooth punch
|
||||
from app.services.fence_checker import _has_attendance_today
|
||||
if not await _has_attendance_today(session, device_id, attendance_type):
|
||||
device = await session.get(Device, device_id)
|
||||
att_record = AttendanceRecord(
|
||||
device_id=device_id,
|
||||
imei=imei,
|
||||
attendance_type=attendance_type,
|
||||
attendance_source="bluetooth",
|
||||
protocol_number=pkt["protocol"],
|
||||
gps_positioned=False,
|
||||
latitude=beacon_lat,
|
||||
longitude=beacon_lon,
|
||||
address=beacon_addr,
|
||||
battery_level=device.battery_level if device else None,
|
||||
gsm_signal=device.gsm_signal if device else None,
|
||||
lbs_data={
|
||||
"source": "bluetooth",
|
||||
"beacon_mac": beacon_mac,
|
||||
"beacon_name": beacon_cfg.name if beacon_cfg else None,
|
||||
},
|
||||
recorded_at=recorded_at,
|
||||
)
|
||||
session.add(att_record)
|
||||
logger.info(
|
||||
"BT attendance created: IMEI=%s type=%s beacon=%s",
|
||||
imei, attendance_type, beacon_mac,
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"BT attendance dedup: IMEI=%s already has %s today",
|
||||
imei, attendance_type,
|
||||
)
|
||||
|
||||
# Broadcast bluetooth punch
|
||||
ws_manager.broadcast_nonblocking("bluetooth", {
|
||||
"imei": imei, "record_type": "punch",
|
||||
"beacon_mac": beacon_mac, "attendance_type": attendance_type,
|
||||
"recorded_at": str(recorded_at),
|
||||
})
|
||||
ws_manager.broadcast_nonblocking("attendance", {
|
||||
"imei": imei, "attendance_type": attendance_type,
|
||||
"latitude": beacon_lat, "longitude": beacon_lon,
|
||||
"address": beacon_addr, "recorded_at": str(recorded_at),
|
||||
"source": "bluetooth",
|
||||
})
|
||||
except Exception:
|
||||
logger.exception("DB error storing BT punch for IMEI=%s", imei)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user