794 lines
31 KiB
Python
794 lines
31 KiB
Python
# -*- coding:utf-8 -*-
|
|
"""
|
|
@Author : xuxingchen
|
|
@Contact : xuxingchen@sinochem.com
|
|
@Desc : 设备信息表 增&改&查
|
|
"""
|
|
import csv
|
|
import os
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel, field_validator
|
|
|
|
from device.call import ServicesCall, DelFaceItem, AddFaceItem
|
|
from models.houses import HousesTable
|
|
from utils import logger
|
|
from utils.database import BaseTable, get_table_handler
|
|
from utils.misc import InvalidException, now_datetime_second, decrypt_number
|
|
|
|
|
|
class DeviceRegister(BaseModel):
|
|
device_mac: str
|
|
device_name: str
|
|
device_desc: str
|
|
third_local_device_id: str
|
|
device_status: str = "离线"
|
|
device_sct: Optional[str] = None
|
|
# 以下需要查询已注册设备信息获取
|
|
gateway_id: Optional[int] = None
|
|
gateway_name: Optional[str] = None
|
|
# 以下需要查询产品信息表获取
|
|
product_name: str
|
|
node_type: str
|
|
|
|
|
|
class Device(BaseModel):
|
|
device_id: int
|
|
device_name: str
|
|
node_type: str
|
|
product_name: str
|
|
|
|
|
|
class AccessDevice(BaseModel):
|
|
device_id: int
|
|
building_ids: list[str]
|
|
|
|
@field_validator("device_id")
|
|
def check_device_id(cls, value):
|
|
th = get_table_handler()
|
|
if DevicesTable.bind_exits(th, value):
|
|
raise InvalidException(f"设备:{value} 已被添加过关联")
|
|
if not DevicesTable.exits(th, value):
|
|
raise InvalidException(f"设备:{value} 不存在")
|
|
return value
|
|
|
|
@field_validator("building_ids")
|
|
def check_authorized_scope(cls, value):
|
|
th = get_table_handler()
|
|
for i in value:
|
|
if not HousesTable.building_exists(th, i):
|
|
raise InvalidException(f"楼栋:{i} 不存在")
|
|
return value
|
|
|
|
|
|
class AccessDevicesScope(BaseModel):
|
|
device_type: str
|
|
info: List[AccessDevice]
|
|
|
|
@field_validator("device_type")
|
|
def check_device_type(cls, value):
|
|
if value in ["大门闸机", "大门门禁"]:
|
|
return value
|
|
else:
|
|
raise InvalidException("请提供正确的设备类型:[大门闸机, 大门门禁]")
|
|
|
|
|
|
class BuildingDevice(BaseModel):
|
|
device_id: int
|
|
bind_unit_id: str
|
|
|
|
@field_validator("device_id")
|
|
def check_device_id(cls, value):
|
|
th = get_table_handler()
|
|
if DevicesTable.bind_exits(th, value):
|
|
raise InvalidException(f"设备:{value} 已被添加过关联")
|
|
if not DevicesTable.exits(th, value):
|
|
raise InvalidException(f"设备:{value} 不存在")
|
|
return value
|
|
|
|
@field_validator("bind_unit_id")
|
|
def check_bind_unit_id(cls, value):
|
|
th = get_table_handler()
|
|
if not HousesTable.unit_exists(th, value):
|
|
raise InvalidException(f"单元:{value} 不存在")
|
|
return value
|
|
|
|
|
|
class BuildingDevicesScope(BaseModel):
|
|
info: List[BuildingDevice]
|
|
|
|
|
|
class SearchDevicesInfo(BaseModel):
|
|
search_type: Optional[str] = None
|
|
search_key: Optional[str] = None
|
|
|
|
@field_validator("search_type")
|
|
def check_search_type(cls, value):
|
|
types = {
|
|
"设备名称": "device_name",
|
|
"MAC地址": "device_mac",
|
|
"设备ID": "device_id"
|
|
}
|
|
if value in types:
|
|
return types[value]
|
|
else:
|
|
raise InvalidException(f"请提供正确的类型:{list(types.keys())}")
|
|
|
|
|
|
class DevicesTable(BaseTable):
|
|
@staticmethod
|
|
def check(table_handler: BaseTable):
|
|
"""检测是否存在当前表"""
|
|
table_handler.query("SELECT name FROM sqlite_master WHERE type='table' AND name='devices'")
|
|
if table_handler.cursor.fetchone() is None:
|
|
table_handler.execute(
|
|
f"""
|
|
CREATE TABLE devices (
|
|
device_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
device_mac TEXT UNIQUE,
|
|
device_name TEXT,
|
|
device_desc TEXT,
|
|
third_local_device_id TEXT,
|
|
device_status TEXT,
|
|
device_sct TEXT,
|
|
gateway_id INTEGER,
|
|
gateway_name TEXT,
|
|
product_name TEXT,
|
|
node_type TEXT,
|
|
last_online_datetime TEXT,
|
|
register_datetime TEXT
|
|
)
|
|
"""
|
|
)
|
|
init_config_path = os.path.join(os.path.dirname(os.path.abspath("__file__")), "data/InitialData/devices.csv")
|
|
if os.path.exists(init_config_path):
|
|
with open(init_config_path, newline='', encoding='utf8') as csvfile:
|
|
csvreader = csv.reader(csvfile)
|
|
head = next(csvreader)
|
|
data = []
|
|
if len(head) == 12:
|
|
for row in csvreader:
|
|
device_mac = row[0].strip()
|
|
device_name = row[1].strip()
|
|
device_desc = row[2].strip() if row[2].strip() else None
|
|
third_local_device_id = row[3].strip() if row[3].strip() else None
|
|
device_status = row[4].strip() if row[4].strip() else "离线"
|
|
device_sct = row[5].strip() if row[5].strip() else None
|
|
gateway_id = int(row[6].strip()) if row[6].strip() else None
|
|
gateway_name = row[7].strip() if row[7].strip() else None
|
|
product_name = row[8].strip()
|
|
node_type = row[9].strip()
|
|
last_online_datetime = row[10].strip() if row[10].strip() else None
|
|
register_datetime = row[11].strip() if row[11].strip() else None
|
|
data.append((device_mac, device_name, device_desc, third_local_device_id, device_status,
|
|
device_sct, gateway_id, gateway_name, product_name, node_type,
|
|
last_online_datetime, register_datetime))
|
|
table_handler.executemany(
|
|
f"""
|
|
INSERT INTO devices
|
|
(device_mac, device_name, device_desc, third_local_device_id, device_status,
|
|
device_sct, gateway_id, gateway_name, product_name, node_type,
|
|
last_online_datetime, register_datetime)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT (device_mac) DO NOTHING
|
|
""",
|
|
data
|
|
)
|
|
|
|
table_handler.query("SELECT name FROM sqlite_master WHERE type='table' AND name='devices_scope'")
|
|
if table_handler.cursor.fetchone() is None:
|
|
table_handler.execute(
|
|
f"""
|
|
CREATE TABLE devices_scope (
|
|
device_id INT,
|
|
device_type TEXT,
|
|
bind_unit_id TEXT,
|
|
UNIQUE (device_id, bind_unit_id)
|
|
)
|
|
"""
|
|
)
|
|
init_config_path = os.path.join(os.path.dirname(os.path.abspath("__file__")),
|
|
"data/InitialData/devices_scope.csv")
|
|
if os.path.exists(init_config_path):
|
|
with open(init_config_path, newline='', encoding='utf8') as csvfile:
|
|
csvreader = csv.reader(csvfile)
|
|
head = next(csvreader)
|
|
data = []
|
|
if len(head) == 3:
|
|
for row in csvreader:
|
|
device_id = row[0].strip()
|
|
device_type = row[1].strip()
|
|
bind_unit_id = row[2].strip()
|
|
data.append((device_id, device_type, bind_unit_id))
|
|
table_handler.executemany(
|
|
f"""
|
|
INSERT INTO devices_scope
|
|
(device_id, device_type, bind_unit_id)
|
|
VALUES (?, ?, ?)
|
|
ON CONFLICT (device_id, bind_unit_id) DO NOTHING
|
|
""", data
|
|
)
|
|
|
|
table_handler.query("SELECT name FROM sqlite_master WHERE type='table' AND name='devices_auth'")
|
|
if table_handler.cursor.fetchone() is None:
|
|
table_handler.execute(
|
|
f"""
|
|
CREATE TABLE devices_auth (
|
|
device_id INT,
|
|
_id TEXT,
|
|
record_type TEXT,
|
|
start_date TEXT,
|
|
expire_date TEXT,
|
|
add_datetime TEXT,
|
|
update_datetime TEXT,
|
|
UNIQUE (device_id, _id, record_type)
|
|
)
|
|
"""
|
|
)
|
|
|
|
init_config_path = os.path.join(os.path.dirname(os.path.abspath("__file__")),
|
|
"data/InitialData/devices_auth.csv")
|
|
if os.path.exists(init_config_path):
|
|
with open(init_config_path, newline='', encoding='utf8') as csvfile:
|
|
csvreader = csv.reader(csvfile)
|
|
head = next(csvreader)
|
|
data = []
|
|
if len(head) == 5:
|
|
for row in csvreader:
|
|
device_id = row[0].strip()
|
|
_id = row[1].strip()
|
|
record_type = row[2].strip()
|
|
start_date = row[3].strip()
|
|
expire_date = row[4].strip()
|
|
data.append((device_id, _id, record_type, start_date, expire_date,
|
|
now_datetime_second(), now_datetime_second()))
|
|
table_handler.executemany(
|
|
f"""
|
|
INSERT INTO devices_auth
|
|
(device_id, _id, record_type, start_date, expire_date, add_datetime, update_datetime)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT (device_id, _id, record_type) DO NOTHING
|
|
""", data
|
|
)
|
|
|
|
@staticmethod
|
|
def insert_by_device_register(table_handler: BaseTable, obj: DeviceRegister):
|
|
register_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
table_handler.execute(
|
|
"""
|
|
INSERT INTO devices
|
|
(device_mac, device_name, device_desc, third_local_device_id, device_status, device_sct,
|
|
gateway_id, gateway_name, product_name, node_type, register_datetime)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT (device_mac) DO UPDATE SET
|
|
device_name=?, device_desc=?, third_local_device_id=?,
|
|
device_status=?, device_sct=?, gateway_id=?, gateway_name=?,
|
|
product_name=?, node_type=?, register_datetime=?
|
|
""",
|
|
(obj.device_mac, obj.device_name, obj.device_desc, obj.third_local_device_id,
|
|
obj.device_status, obj.device_sct, obj.gateway_id, obj.gateway_name,
|
|
obj.product_name, obj.node_type, register_datetime,
|
|
obj.device_name, obj.device_desc, obj.third_local_device_id,
|
|
obj.device_status, obj.device_sct, obj.gateway_id, obj.gateway_name,
|
|
obj.product_name, obj.node_type, register_datetime)
|
|
)
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_id
|
|
FROM devices
|
|
WHERE device_mac = ?
|
|
""",
|
|
(obj.device_mac,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return res[0][0]
|
|
return None
|
|
|
|
@staticmethod
|
|
def insert_device_auth_record(table_handler: BaseTable, device_id: int, _id: str,
|
|
start_date: str, expire_date: str, record_type: str = '人行'):
|
|
table_handler.execute(
|
|
"""
|
|
INSERT INTO devices_auth
|
|
(device_id, _id, record_type, start_date, expire_date, add_datetime, update_datetime)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT (device_id, _id, record_type) DO UPDATE SET
|
|
start_date=?, expire_date=?, update_datetime=?
|
|
""",
|
|
(device_id, _id, record_type, start_date, expire_date,
|
|
now_datetime_second(), now_datetime_second(), start_date, expire_date, now_datetime_second())
|
|
)
|
|
|
|
@staticmethod
|
|
def get_devices_info(table_handler: BaseTable):
|
|
"""获取对应设备的基本信息"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_name, third_local_device_id, device_id, device_status,
|
|
gateway_name, product_name, node_type, last_online_datetime, register_datetime
|
|
FROM devices
|
|
WHERE node_type != '网关设备'
|
|
"""
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
devices_info = []
|
|
for item in res:
|
|
devices_info.append({
|
|
"device_name": item[0],
|
|
"third_local_device_id": item[1],
|
|
"device_id": item[2],
|
|
"device_status": item[3],
|
|
"gateway_name": item[4] if item[4] else "",
|
|
"product_name": item[5],
|
|
"node_type": item[6],
|
|
"last_online_datetime": item[7] if item[7] else "",
|
|
"register_datetime": item[8]
|
|
})
|
|
return devices_info
|
|
return None
|
|
|
|
@staticmethod
|
|
def get_device_info(table_handler: BaseTable, device_id: int):
|
|
"""获取对应设备的基本信息"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_name, node_type, product_name
|
|
FROM devices
|
|
WHERE device_id = ?
|
|
""",
|
|
(device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return Device(device_id=device_id, device_name=res[0][0], node_type=res[0][1], product_name=res[0][2])
|
|
return None
|
|
|
|
@staticmethod
|
|
def get_device_name(table_handler: BaseTable, device_id: int):
|
|
"""获取对应设备名"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_name
|
|
FROM devices
|
|
WHERE device_id = ?
|
|
""",
|
|
(device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return res[0][0]
|
|
return ""
|
|
|
|
@staticmethod
|
|
def get_device_scope_type(table_handler: BaseTable, device_id: int):
|
|
"""获取对应设备门禁类型"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_type
|
|
FROM devices_scope
|
|
WHERE device_id = ?
|
|
""",
|
|
(device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return res[0][0]
|
|
return ""
|
|
|
|
@staticmethod
|
|
def get_device_ids_by_unit_id(table_handler: BaseTable, unit_id: str) -> list:
|
|
"""查询对应单元权限内的设备ID"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT GROUP_CONCAT(device_id) AS device_ids
|
|
FROM devices_scope
|
|
WHERE bind_unit_id = ?
|
|
""", (unit_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return res[0][0].split(',')
|
|
else:
|
|
return []
|
|
|
|
@staticmethod
|
|
def get_device_ids(table_handler: BaseTable, filter_name: Optional[str] = None, filter_online: bool = True):
|
|
"""获取相关的设备ID"""
|
|
sub_sql_list = []
|
|
if filter_online:
|
|
sub_sql_list.append("device_status = '在线'")
|
|
if filter_name is not None:
|
|
sub_sql_list.append(f"product_name like '%{filter_name}%'")
|
|
if len(sub_sql_list) > 0:
|
|
sub_sql = "WHERE " + " AND ".join(sub_sql_list)
|
|
else:
|
|
sub_sql = ""
|
|
table_handler.query(f"SELECT GROUP_CONCAT(device_id) device_ids FROM devices {sub_sql}")
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return [i for i in res[0][0].split(',')]
|
|
else:
|
|
return []
|
|
|
|
@staticmethod
|
|
def get_auth_interval(table_handler: BaseTable, _id: str, device_id: int, record_type: str = '人行'):
|
|
"""获取对应ID授权在设备上的有效期"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT start_date, expire_date
|
|
FROM devices_auth
|
|
WHERE device_id = ? and _id = ? and record_type = ?
|
|
""",
|
|
(device_id, _id, record_type)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return res[0][0], res[0][1]
|
|
return "", ""
|
|
|
|
@staticmethod
|
|
def update_device_status(table_handler: BaseTable, device_id: int, device_status: str):
|
|
"""更新设备在线状态"""
|
|
if device_status == "在线":
|
|
last_online_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
set_sql = f"device_status='在线', last_online_datetime='{last_online_datetime}' "
|
|
else:
|
|
set_sql = f"device_status='离线' "
|
|
table_handler.execute(
|
|
f"""
|
|
UPDATE devices SET {set_sql}
|
|
WHERE device_id={device_id}
|
|
"""
|
|
)
|
|
|
|
@staticmethod
|
|
def offline_gateway(table_handler: BaseTable, device_id: int):
|
|
"""用于在网关下线时同时下线网关下的所有设备"""
|
|
table_handler.execute(
|
|
f"""
|
|
UPDATE devices SET device_status='离线'
|
|
WHERE device_id={device_id} or gateway_id={device_id}
|
|
"""
|
|
)
|
|
|
|
@staticmethod
|
|
def get_access_devices_info(table_handler: BaseTable,
|
|
is_associated: bool,
|
|
device_name: str = None,
|
|
product_name: str = None,
|
|
device_mac: str = None,
|
|
device_id: int = None):
|
|
if is_associated:
|
|
sub_sql = "WHERE d.node_type != '网关设备' AND product_name not like '%停车场%' AND device_type is not null "
|
|
else:
|
|
sub_sql = "WHERE d.node_type != '网关设备' AND product_name not like '%停车场%' AND device_type is null "
|
|
if device_name:
|
|
sub_sql += f"AND device_name = '{device_name}'"
|
|
elif product_name:
|
|
sub_sql += f"AND product_name = '{product_name}'"
|
|
elif device_mac:
|
|
sub_sql += f"AND device_mac = '{device_mac}'"
|
|
elif device_id:
|
|
sub_sql += f"AND d.device_id = {device_id}"
|
|
table_handler.query(
|
|
f"""
|
|
SELECT
|
|
d.device_id,
|
|
device_name,
|
|
device_mac,
|
|
device_status,
|
|
ds.device_type,
|
|
GROUP_CONCAT(t.building_name || '-' || t.unit_name) as scopes,
|
|
product_name
|
|
FROM devices d
|
|
LEFT JOIN devices_scope ds ON ds.device_id = d.device_id
|
|
LEFT JOIN (SELECT DISTINCT unit_id, unit_name, building_id, building_name FROM houses) t
|
|
ON t.unit_id = ds.bind_unit_id
|
|
{sub_sql}
|
|
GROUP BY d.device_id, device_name, device_mac, device_status, ds.device_type, product_name
|
|
"""
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
devices_info = []
|
|
for i in res:
|
|
devices_info.append({
|
|
"device_id": i[0],
|
|
"device_name": i[1],
|
|
"device_mac": i[2],
|
|
"device_status": i[3],
|
|
"device_type": i[4] if i[4] else "",
|
|
"authorized_scope": i[5].split(",") if i[5] else [],
|
|
"product_name": i[6]
|
|
})
|
|
return {"devices": devices_info}
|
|
return {"devices": []}
|
|
|
|
@staticmethod
|
|
def get_associated_access_devices_info(table_handler: BaseTable,
|
|
search_type: Optional[str] = None,
|
|
search_key: Optional[str] = None):
|
|
if search_type:
|
|
if search_type == "device_id":
|
|
sub_sql = f"WHERE ds.device_id = {search_key}"
|
|
elif search_type == "device_name":
|
|
sub_sql = f"WHERE d.device_name like '%{search_key}%'"
|
|
else:
|
|
sub_sql = f"WHERE d.{search_type} = '{search_key}'"
|
|
else:
|
|
sub_sql = ""
|
|
table_handler.query(
|
|
f"""
|
|
SELECT ds.device_id as _id,
|
|
d.device_name as _name,
|
|
d.device_mac as _mac,
|
|
d.device_status as _status
|
|
FROM (SELECT DISTINCT device_id FROM devices_scope) ds
|
|
LEFT JOIN devices d ON ds.device_id = d.device_id
|
|
{sub_sql}
|
|
"""
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
devices_info = []
|
|
for i in res:
|
|
devices_info.append({
|
|
"device_id": i[0],
|
|
"device_name": i[1],
|
|
"device_mac": i[2],
|
|
"device_status": i[3]
|
|
})
|
|
return {"devices": devices_info}
|
|
return {"devices": []}
|
|
|
|
@staticmethod
|
|
def auto_auth_by_unit_id(table_handler: BaseTable, device_id: int, unit_id: str):
|
|
"""查询对应单元下相关住户,对具备人脸的住户授权"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT h.householder_id, name, phone, face_url
|
|
FROM householders h
|
|
LEFT JOIN householders_type ht ON ht.householder_id=h.householder_id
|
|
LEFT JOIN houses ON ht.room_id=houses.room_id
|
|
WHERE h.type = '住户' AND (face_url != '' or face_url is not null ) AND houses.unit_id = ?
|
|
""", (unit_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
# 人员人脸下放
|
|
for i in res:
|
|
sc = ServicesCall()
|
|
face_item = AddFaceItem(
|
|
user_id=i[0],
|
|
name=i[1],
|
|
phone_number=decrypt_number(i[2]),
|
|
face_url=i[3],
|
|
device_ids=str([device_id])
|
|
)
|
|
_callback, code, msg = sc.add_face(device_id, face_item)
|
|
if _callback:
|
|
DevicesTable.insert_device_auth_record(table_handler, device_id, face_item.user_id,
|
|
face_item.start_date, face_item.expire_date)
|
|
|
|
@staticmethod
|
|
def add_access_devices(table_handler: BaseTable, device_type: str, objs: List[AccessDevice]):
|
|
data = []
|
|
for obj in objs:
|
|
for bind_building_id in obj.building_ids:
|
|
unit_ids = HousesTable.get_unit_ids(table_handler, bind_building_id)
|
|
for unit_id in unit_ids:
|
|
data.append((obj.device_id, device_type, unit_id, device_type))
|
|
DevicesTable.auto_auth_by_unit_id(table_handler, obj.device_id, unit_id)
|
|
try:
|
|
table_handler.executemany(
|
|
"""
|
|
INSERT INTO devices_scope
|
|
(device_id, device_type, bind_unit_id)
|
|
VALUES (?, ?, ?)
|
|
ON CONFLICT (device_id, bind_unit_id) DO UPDATE
|
|
SET device_type = ?
|
|
""", data
|
|
)
|
|
return True
|
|
except Exception as e:
|
|
logger.Logger.error(f"DevicesTable.add_access_devices: {type(e).__name__}, {e}")
|
|
raise InvalidException(f"DevicesTable.add_access_devices: {type(e).__name__}, {e}")
|
|
|
|
@staticmethod
|
|
def add_building_devices(table_handler: BaseTable, device_type: str, objs: List[BuildingDevice]):
|
|
data = []
|
|
for obj in objs:
|
|
data.append((obj.device_id, device_type, obj.bind_unit_id))
|
|
DevicesTable.auto_auth_by_unit_id(table_handler, obj.device_id, obj.bind_unit_id)
|
|
try:
|
|
table_handler.executemany(
|
|
"""
|
|
INSERT INTO devices_scope
|
|
(device_id, device_type, bind_unit_id)
|
|
VALUES (?, ?, ?)
|
|
ON CONFLICT (device_id, bind_unit_id) DO NOTHING
|
|
""", data
|
|
)
|
|
return True
|
|
except Exception as e:
|
|
logger.Logger.error(f"DevicesTable.add_building_devices: {type(e).__name__}, {e}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def add_update_device_auth(table_handler: BaseTable, device_id, _ids: list[str], record_type: str,
|
|
start_date: str, expire_date: str):
|
|
"""对应设备批量授权记录增加"""
|
|
data = []
|
|
for _id in _ids:
|
|
_datetime = now_datetime_second()
|
|
data.append((device_id, _id, record_type, start_date, expire_date, _datetime, _datetime,
|
|
start_date, expire_date, _datetime))
|
|
try:
|
|
table_handler.executemany(
|
|
"""
|
|
INSERT INTO devices_auth
|
|
(device_id, _id, record_type, start_date, expire_date, add_datetime, update_datetime)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT (device_id, _id, record_type)
|
|
DO UPDATE SET start_date = ?, expire_date = ?, update_datetime = ?
|
|
""", data
|
|
)
|
|
return True
|
|
except Exception as e:
|
|
logger.Logger.error(f"DevicesTable.add_device_auth: {type(e).__name__}, {e}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def get_auth_device_ids(table_handler: BaseTable, _id: str, record_type: str = '人行'):
|
|
"""获取ID的所有授权设备"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_id
|
|
FROM devices_auth
|
|
WHERE _id = ? AND record_type = ?
|
|
""", (_id, record_type)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return [i[0] for i in res]
|
|
else:
|
|
return []
|
|
|
|
@staticmethod
|
|
def get_auth_device_info(table_handler: BaseTable, _id: str, record_type: str = '人行'):
|
|
"""获取ID当前所有授权设备基础信息"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT devices_auth.device_id, device_name, device_mac, device_status
|
|
FROM devices_auth
|
|
LEFT JOIN devices ON devices.device_id = devices_auth.device_id
|
|
WHERE _id = ? AND record_type = ?
|
|
""", (_id, record_type)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return [{"device_id": i[0], "device_name": i[1], "device_mac": i[2], "device_status": i[3]} for i in res]
|
|
else:
|
|
return []
|
|
|
|
@staticmethod
|
|
def get_auth_householders_info(table_handler: BaseTable, device_id: int):
|
|
"""获取关联授权下的所有完成下放的人员信息"""
|
|
table_handler.query(
|
|
"""
|
|
SELECT da._id, name, phone, face_url, da.start_date, da.expire_date
|
|
FROM devices_auth da
|
|
LEFT JOIN householders h ON da._id = h.householder_id
|
|
WHERE device_id = ? AND record_type = '人行'
|
|
""", (device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return [{"id": i[0], "name": i[1], "phone": i[2], "url": i[3], "sdate": i[4], "edate": i[5]} for i in res]
|
|
else:
|
|
return []
|
|
|
|
@staticmethod
|
|
def delete_householder_all_auth(table_handler: BaseTable, _id: str):
|
|
table_handler.execute(
|
|
"""
|
|
DELETE FROM devices_auth
|
|
WHERE _id = ? AND record_type = '人行'
|
|
""", (_id,)
|
|
)
|
|
|
|
@staticmethod
|
|
def delete_invalid_auth_record(table_handler: BaseTable, device_id: int, _id: str, record_type: str = '人行'):
|
|
table_handler.execute(
|
|
"""
|
|
DELETE FROM devices_auth
|
|
WHERE device_id = ? AND _id = ? AND record_type = ?
|
|
""",
|
|
(device_id, _id, record_type)
|
|
)
|
|
|
|
@staticmethod
|
|
def delete_access_device_info(table_handler: BaseTable, device_id: int):
|
|
# 1. 确认设备ID有效
|
|
if not DevicesTable.exits(table_handler, device_id):
|
|
raise InvalidException(f"设备:{device_id} 不存在")
|
|
# 2. 获取关联授权下的所有完成下放的人员信息
|
|
householder_infos = DevicesTable.get_auth_householders_info(table_handler, device_id)
|
|
if len(householder_infos) > 0:
|
|
# 3. 移除对应设备中所有的人员信息
|
|
sc = ServicesCall()
|
|
success_ids = []
|
|
for index, householder_info in enumerate(householder_infos):
|
|
_callback, code, _ = sc.del_face(device_id,
|
|
DelFaceItem(user_id=str(householder_info["id"]),
|
|
device_ids=str([device_id])))
|
|
if not _callback:
|
|
# 存在异常时,回滚已删除掉的人脸
|
|
failed = []
|
|
msgs = []
|
|
for success_id in success_ids:
|
|
_back, code, msg = sc.add_face(device_id, AddFaceItem(
|
|
name=householder_infos[success_id]["name"],
|
|
user_id=str(householder_infos[success_id]["id"]),
|
|
phone_number=householder_infos[success_id]["phone"],
|
|
face_url=householder_infos[success_id]["url"],
|
|
device_ids=str([device_id]),
|
|
start_date=householder_infos[success_id]["sdate"],
|
|
expire_date=householder_infos[success_id]["edate"]
|
|
))
|
|
if not _back:
|
|
failed.append(householder_infos[success_id]["id"])
|
|
msgs.append(msg)
|
|
if len(failed) == 0:
|
|
raise InvalidException(
|
|
f"住户 - {householder_info['id']} 人脸授权移除失败,错误码{code}, {msgs}, 已完成回滚")
|
|
else:
|
|
raise InvalidException(
|
|
f"住户 - {householder_info['id']} 人脸授权移除失败,错误码{code}, {msgs}, 回滚失败")
|
|
success_ids.append(index)
|
|
# 4. 移除设备的关联记录
|
|
table_handler.execute(
|
|
"""
|
|
DELETE FROM devices_auth
|
|
WHERE device_id = ? AND record_type = '人行'
|
|
""", (device_id,)
|
|
)
|
|
table_handler.execute(
|
|
"""
|
|
DELETE FROM devices_scope
|
|
WHERE device_id = ?
|
|
""", (device_id,)
|
|
)
|
|
return {"status": True}
|
|
|
|
@staticmethod
|
|
def exits(table_handler: BaseTable, device_id: int):
|
|
table_handler.query(
|
|
"""
|
|
SELECT device_id FROM devices
|
|
WHERE device_id = ?
|
|
""", (device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
@staticmethod
|
|
def bind_exits(table_handler: BaseTable, device_id: int):
|
|
table_handler.query(
|
|
"""
|
|
SELECT bind_unit_id
|
|
FROM devices_scope
|
|
WHERE device_id = ?
|
|
""", (device_id,)
|
|
)
|
|
res = table_handler.cursor.fetchall()
|
|
if res:
|
|
return True
|
|
else:
|
|
return False
|