牧安云哨-后端
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from .aimessage import *
|
||||
from .aiprofile import *
|
||||
from .aisession import *
|
||||
from .iot import *
|
||||
from .knowledge import *
|
||||
from .license import *
|
||||
from .report import *
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
from hashlib import sha256
|
||||
|
||||
from config.pgDb import pg_pool
|
||||
from utils.MyUtils import format_datetime, is_valid_uuid
|
||||
|
||||
|
||||
def get_device_list_db_page(
|
||||
page: int,
|
||||
page_size: int,
|
||||
device_id=None,
|
||||
name=None,
|
||||
status=None,
|
||||
is_superuser=None,
|
||||
dept_id=None,
|
||||
startTime=None,
|
||||
endTime=None,
|
||||
):
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
conditions = []
|
||||
params = []
|
||||
|
||||
# ---- 设备 ID(uuid)----
|
||||
if device_id:
|
||||
conditions.append("d.id::text LIKE %s")
|
||||
params.append(f"%{device_id}%")
|
||||
|
||||
# ---- 设备名模糊搜索 ----
|
||||
if name:
|
||||
conditions.append("d.name LIKE %s")
|
||||
params.append(f"%{name}%")
|
||||
|
||||
# ---- 状态 ----
|
||||
if status is not None:
|
||||
conditions.append("d.is_active = %s")
|
||||
params.append(status == 1)
|
||||
|
||||
# ---- 状态 ----
|
||||
if is_superuser is not None:
|
||||
conditions.append("d.is_superuser = %s")
|
||||
params.append(is_superuser == 1)
|
||||
|
||||
# ---- 部门 ----
|
||||
if dept_id and is_valid_uuid(dept_id):
|
||||
conditions.append("d.dept_id = %s")
|
||||
params.append(dept_id)
|
||||
|
||||
# ---- 时间过滤 ----
|
||||
if startTime:
|
||||
conditions.append("d.created_at >= %s")
|
||||
params.append(startTime)
|
||||
|
||||
if endTime:
|
||||
conditions.append("d.created_at <= %s")
|
||||
params.append(endTime)
|
||||
|
||||
where_clause = " WHERE " + " AND ".join(conditions) if conditions else ""
|
||||
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
|
||||
# ---- 统计总数 ----
|
||||
count_sql = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM iot_users d
|
||||
{where_clause};
|
||||
"""
|
||||
cursor.execute(count_sql, params)
|
||||
total = cursor.fetchone()[0]
|
||||
|
||||
# ---- 分页查询 ----
|
||||
list_sql = f"""
|
||||
SELECT
|
||||
d.id,
|
||||
d.name,
|
||||
d.remark,
|
||||
d.is_active,
|
||||
d.is_superuser,
|
||||
d.dept_id,
|
||||
sd.name AS dept_name,
|
||||
d.created_at
|
||||
FROM iot_users d
|
||||
LEFT JOIN sys_dept sd ON d.dept_id = sd.id
|
||||
{where_clause}
|
||||
ORDER BY d.created_at DESC
|
||||
LIMIT %s OFFSET %s;
|
||||
"""
|
||||
|
||||
cursor.execute(list_sql, params + [page_size, offset])
|
||||
rows = cursor.fetchall()
|
||||
|
||||
result = []
|
||||
for r in rows:
|
||||
(
|
||||
device_id,
|
||||
name,
|
||||
remark,
|
||||
is_active,
|
||||
is_superuser,
|
||||
dept_id,
|
||||
dept_name,
|
||||
created_at,
|
||||
) = r
|
||||
|
||||
result.append(
|
||||
{
|
||||
"id": device_id,
|
||||
"name": name,
|
||||
"remark": remark,
|
||||
"status": 1 if is_active else 0,
|
||||
"is_superuser": 1 if is_superuser else 0,
|
||||
"dept_id": dept_id,
|
||||
"dept_name": dept_name,
|
||||
"created_at": format_datetime(created_at),
|
||||
}
|
||||
)
|
||||
|
||||
return result, total
|
||||
|
||||
|
||||
def insert_device(data: dict) -> str:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
name = data.get("name")
|
||||
salt = name[-4:] if name else ""
|
||||
password = data.get("password", "123456")
|
||||
password_hash = sha256((salt + password).encode("utf-8")).hexdigest()
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO iot_users (name, password_hash, salt, remark, dept_id, is_active, is_superuser)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||||
RETURNING id;
|
||||
""",
|
||||
(
|
||||
name,
|
||||
password_hash,
|
||||
salt,
|
||||
data.get("remark"),
|
||||
data.get("dept_id"),
|
||||
bool(data.get("status", 1)),
|
||||
bool(data.get("is_superuser", 0)),
|
||||
),
|
||||
)
|
||||
device_id = cursor.fetchone()[0]
|
||||
conn.commit()
|
||||
return device_id
|
||||
|
||||
|
||||
def update_device_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE iot_users
|
||||
SET remark=%s, is_active=%s, dept_id=%s, is_superuser=%s
|
||||
WHERE id=%s;
|
||||
""",
|
||||
(
|
||||
data.get("remark"),
|
||||
bool(data.get("status", 1)),
|
||||
data.get("dept_id"),
|
||||
bool(data.get("is_superuser", 0)),
|
||||
id,
|
||||
),
|
||||
)
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def patch_device_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
fields = []
|
||||
params = []
|
||||
mapping = {
|
||||
"remark": "remark",
|
||||
"status": "is_active",
|
||||
"is_superuser": "is_superuser",
|
||||
"dept_id": "dept_id",
|
||||
}
|
||||
for k, column in mapping.items():
|
||||
if k in data:
|
||||
value = (
|
||||
bool(data[k]) if k in ["status", "is_superuser"] else data[k]
|
||||
)
|
||||
fields.append(f"{column} = %s")
|
||||
params.append(value)
|
||||
|
||||
if fields:
|
||||
sql = f"UPDATE iot_users SET {', '.join(fields)} WHERE id = %s"
|
||||
params.append(id)
|
||||
cursor.execute(sql, tuple(params))
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def delete_device_db(id: str) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("DELETE FROM iot_users WHERE id=%s;", (id,))
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
@@ -0,0 +1,261 @@
|
||||
from config.minIO import get_temp_url_dict
|
||||
from config.pgDb import pg_pool
|
||||
from utils.MyUtils import format_datetime
|
||||
|
||||
|
||||
def get_sentinel_record_list_db_page(
|
||||
page: int,
|
||||
page_size: int,
|
||||
record_id=None,
|
||||
license_plate=None,
|
||||
vehicle_type=None,
|
||||
is_inspected=None,
|
||||
livestock_source=None,
|
||||
livestock_type=None,
|
||||
dept_ids=None,
|
||||
start_time=None,
|
||||
end_time=None,
|
||||
):
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
conditions = []
|
||||
params = []
|
||||
|
||||
# ---- 记录 ID ----
|
||||
if record_id:
|
||||
conditions.append("r.id::text LIKE %s")
|
||||
params.append(f"%{record_id}%")
|
||||
|
||||
# ---- 车牌号 ----
|
||||
if license_plate:
|
||||
conditions.append("r.license_plate LIKE %s")
|
||||
params.append(f"%{license_plate}%")
|
||||
|
||||
# ---- 车型 ----
|
||||
if vehicle_type:
|
||||
conditions.append("r.vehicle_type LIKE %s")
|
||||
params.append(f"%{vehicle_type}%")
|
||||
|
||||
# ---- 是否检查 ----
|
||||
if is_inspected is not None:
|
||||
conditions.append("r.is_inspected = %s")
|
||||
params.append(bool(is_inspected))
|
||||
|
||||
# ---- 来源 ----
|
||||
if livestock_source is not None:
|
||||
conditions.append("r.livestock_source LIKE %s")
|
||||
params.append(f"%{livestock_source}%")
|
||||
|
||||
# ---- 种类 ----
|
||||
if livestock_type is not None:
|
||||
conditions.append("r.livestock_type LIKE %s")
|
||||
params.append(livestock_type)
|
||||
|
||||
# ---- 部门 ----
|
||||
if dept_ids:
|
||||
conditions.append("r.dept_id = ANY(%s)")
|
||||
params.append(dept_ids)
|
||||
|
||||
# ---- 时间过滤 ----
|
||||
if start_time:
|
||||
conditions.append("r.created_at >= %s")
|
||||
params.append(start_time)
|
||||
|
||||
if end_time:
|
||||
conditions.append("r.created_at <= %s")
|
||||
params.append(end_time)
|
||||
|
||||
where_clause = " WHERE " + " AND ".join(conditions) if conditions else ""
|
||||
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
|
||||
# ---- 统计总数 ----
|
||||
count_sql = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM sentinel_records r
|
||||
{where_clause};
|
||||
"""
|
||||
cursor.execute(count_sql, params)
|
||||
total = cursor.fetchone()[0]
|
||||
|
||||
# ---- 分页查询 ----
|
||||
list_sql = f"""
|
||||
SELECT
|
||||
r.id,
|
||||
r.license_plate,
|
||||
r.vehicle_type,
|
||||
r.license_plate_image,
|
||||
r.vehicle_image,
|
||||
r.livestock_type,
|
||||
r.livestock_source,
|
||||
r.is_inspected,
|
||||
r.dept_id,
|
||||
sd.name AS dept_name,
|
||||
r.created_at,
|
||||
r.updated_at,
|
||||
r.remark
|
||||
FROM sentinel_records r
|
||||
LEFT JOIN sys_dept sd ON r.dept_id = sd.id
|
||||
{where_clause}
|
||||
ORDER BY r.created_at DESC
|
||||
LIMIT %s OFFSET %s;
|
||||
"""
|
||||
|
||||
cursor.execute(list_sql, params + [page_size, offset])
|
||||
rows = cursor.fetchall()
|
||||
|
||||
result = []
|
||||
for r in rows:
|
||||
(
|
||||
record_id,
|
||||
license_plate,
|
||||
vehicle_type,
|
||||
license_plate_image,
|
||||
vehicle_image,
|
||||
livestock_type,
|
||||
livestock_source,
|
||||
is_inspected,
|
||||
dept_id,
|
||||
dept_name,
|
||||
created_at,
|
||||
updated_at,
|
||||
remark,
|
||||
) = r
|
||||
|
||||
result.append(
|
||||
{
|
||||
"id": record_id,
|
||||
"license_plate": license_plate,
|
||||
"vehicle_type": vehicle_type,
|
||||
"license_plate_image": get_temp_url_dict(
|
||||
"sentinel", "license_plate", license_plate_image
|
||||
),
|
||||
"vehicle_image": get_temp_url_dict(
|
||||
"sentinel", "vehicle_image", vehicle_image
|
||||
),
|
||||
"livestock_type": livestock_type,
|
||||
"livestock_source": livestock_source,
|
||||
"is_inspected": 1 if is_inspected else 0,
|
||||
"dept_id": dept_id,
|
||||
"dept_name": dept_name,
|
||||
"created_at": format_datetime(created_at),
|
||||
"updated_at": format_datetime(updated_at),
|
||||
"remark": remark,
|
||||
}
|
||||
)
|
||||
|
||||
return result, total
|
||||
|
||||
|
||||
def insert_sentinel_record(data: dict, dept_id) -> str:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO sentinel_records (
|
||||
license_plate,
|
||||
vehicle_type,
|
||||
license_plate_image,
|
||||
vehicle_image,
|
||||
livestock_type,
|
||||
livestock_source,
|
||||
is_inspected,
|
||||
dept_id,
|
||||
remark,
|
||||
created_by
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
RETURNING id;
|
||||
""",
|
||||
(
|
||||
data.get("license_plate"),
|
||||
data.get("vehicle_type"),
|
||||
data.get("license_plate_image"),
|
||||
data.get("vehicle_image"),
|
||||
data.get("livestock_type"),
|
||||
data.get("livestock_source"),
|
||||
bool(data.get("is_inspected", False)),
|
||||
dept_id,
|
||||
data.get("remark"),
|
||||
data.get("created_by"),
|
||||
),
|
||||
)
|
||||
record_id = cursor.fetchone()[0]
|
||||
conn.commit()
|
||||
return record_id
|
||||
|
||||
|
||||
def update_sentinel_record_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE sentinel_records
|
||||
SET
|
||||
license_plate = %s,
|
||||
vehicle_type = %s,
|
||||
license_plate_image = %s,
|
||||
vehicle_image = %s,
|
||||
livestock_type = %s,
|
||||
livestock_source = %s,
|
||||
is_inspected = %s,
|
||||
remark = %s,
|
||||
updated_at = now()
|
||||
WHERE id = %s;
|
||||
""",
|
||||
(
|
||||
data.get("license_plate"),
|
||||
data.get("vehicle_type"),
|
||||
data.get("license_plate_image"),
|
||||
data.get("vehicle_image"),
|
||||
data.get("livestock_type"),
|
||||
data.get("livestock_source"),
|
||||
bool(data.get("is_inspected", False)),
|
||||
data.get("remark"),
|
||||
id,
|
||||
),
|
||||
)
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def patch_sentinel_record_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
fields = []
|
||||
params = []
|
||||
mapping = {
|
||||
"license_plate": "license_plate",
|
||||
"vehicle_type": "vehicle_type",
|
||||
"license_plate_image": "license_plate_image",
|
||||
"vehicle_image": "vehicle_image",
|
||||
"livestock_type": "livestock_type",
|
||||
"livestock_source": "livestock_source",
|
||||
"is_inspected": "is_inspected",
|
||||
"remark": "remark",
|
||||
}
|
||||
|
||||
for k, column in mapping.items():
|
||||
if k in data:
|
||||
value = data[k]
|
||||
# 如果字段是 "is_inspected",将其转换为布尔类型
|
||||
if k == "is_inspected":
|
||||
value = bool(value) # 转换为布尔值
|
||||
fields.append(f"{column} = %s")
|
||||
params.append(value)
|
||||
|
||||
if fields:
|
||||
sql = f"UPDATE sentinel_records SET {', '.join(fields)} WHERE id = %s"
|
||||
params.append(id)
|
||||
cursor.execute(sql, tuple(params))
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def delete_sentinel_record_db(id: str) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("DELETE FROM sentinel_records WHERE id=%s;", (id,))
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
@@ -2,6 +2,7 @@ import json
|
||||
from uuid import UUID
|
||||
|
||||
from config.pgDb import pg_pool
|
||||
from utils import MyUtils
|
||||
from utils.MyUtils import format_datetime, is_valid_uuid
|
||||
|
||||
|
||||
@@ -387,7 +388,7 @@ def get_role_list_db_page(page: int, page_size: int, rid=None, name=None, remark
|
||||
"id": role_id,
|
||||
"name": name,
|
||||
"remark": remark,
|
||||
"created_at": created_at,
|
||||
"created_at": format_datetime(created_at),
|
||||
"permissions": menu_ids or [],
|
||||
}
|
||||
)
|
||||
@@ -411,9 +412,9 @@ def get_user_list_db_page(
|
||||
params = []
|
||||
|
||||
# ---- 用户 ID,必须是 UUID,否则忽略 ----
|
||||
if uid and is_valid_uuid(uid):
|
||||
conditions.append("u.id = %s")
|
||||
params.append(uid)
|
||||
if uid:
|
||||
conditions.append("u.id::text LIKE %s")
|
||||
params.append(f"%{uid}%")
|
||||
|
||||
# ---- 用户名模糊搜索 ----
|
||||
if username:
|
||||
@@ -506,19 +507,11 @@ def get_user_list_db_page(
|
||||
return result, total
|
||||
|
||||
|
||||
# 检查用户名是否存在
|
||||
def db_user_name_exists(username: str, id: str | None = None) -> bool:
|
||||
# 检查登录账号是否存在
|
||||
def db_user_name_exists(username: str) -> bool:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
if id:
|
||||
cursor.execute(
|
||||
"SELECT COUNT(*) FROM users WHERE username = %s AND id <> %s;",
|
||||
(username, id),
|
||||
)
|
||||
else:
|
||||
cursor.execute(
|
||||
"SELECT COUNT(*) FROM users WHERE username = %s;", (username,)
|
||||
)
|
||||
cursor.execute("SELECT COUNT(*) FROM users WHERE email = %s;", (username,))
|
||||
return cursor.fetchone()[0] > 0
|
||||
|
||||
|
||||
@@ -554,40 +547,6 @@ def insert_user(data: dict) -> str:
|
||||
return user_id
|
||||
|
||||
|
||||
# 更新用户
|
||||
def update_user_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE users
|
||||
SET username=%s, email=%s, phone=%s, is_active=%s, dept_id=%s
|
||||
WHERE id=%s;
|
||||
""",
|
||||
(
|
||||
data.get("name"),
|
||||
data.get("email"),
|
||||
data.get("phone"),
|
||||
bool(data.get("status", 1)),
|
||||
data.get("dept_id"),
|
||||
id,
|
||||
),
|
||||
)
|
||||
|
||||
# 更新用户角色关系:先删除旧的,再插入新的
|
||||
cursor.execute("DELETE FROM sys_user_role WHERE user_id=%s;", (id,))
|
||||
role_ids = data.get("roles", [])
|
||||
if role_ids:
|
||||
for role_id in role_ids:
|
||||
cursor.execute(
|
||||
"INSERT INTO sys_user_role (user_id, role_id) VALUES (%s, %s);",
|
||||
(id, role_id),
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
# 局部更新用户(PATCH)
|
||||
def patch_user_db(id: str, data: dict) -> int:
|
||||
with pg_pool.getConn() as conn:
|
||||
@@ -603,6 +562,7 @@ def patch_user_db(id: str, data: dict) -> int:
|
||||
"name": "username",
|
||||
"email": "email",
|
||||
"phone": "phone",
|
||||
"password_hash": "password_hash",
|
||||
"status": "is_active",
|
||||
"dept_id": "dept_id",
|
||||
}
|
||||
@@ -676,7 +636,7 @@ def get_menus_by_ids(menu_ids: list, plat_id: int):
|
||||
SELECT id, pid, name, path, component, redirect,
|
||||
auth_code, type, meta, created_at, updated_at
|
||||
FROM sys_menu
|
||||
WHERE id = ANY(%s::varchar[]) AND plat_id = %s
|
||||
WHERE id = ANY(%s::varchar[]) AND plat_id = %s AND type != 'button'
|
||||
ORDER BY created_at ASC;
|
||||
"""
|
||||
# 转换 uuid 列表为 str 列表
|
||||
@@ -697,3 +657,296 @@ def build_menu_tree(items):
|
||||
else:
|
||||
tree.append(item)
|
||||
return tree
|
||||
|
||||
|
||||
def get_dict_list(keyword="", page=1, page_size=10):
|
||||
"""
|
||||
获取系统字典列表,支持分页和关键字搜索(key / name)
|
||||
"""
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
# 1️⃣ 查询总条数
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT COUNT(*)
|
||||
FROM sys_dict
|
||||
WHERE (
|
||||
%s = ''
|
||||
OR key ILIKE '%%' || %s || '%%'
|
||||
OR name ILIKE '%%' || %s || '%%'
|
||||
)
|
||||
""",
|
||||
(keyword, keyword, keyword),
|
||||
)
|
||||
total = cursor.fetchone()[0]
|
||||
|
||||
# 2️⃣ 查询当前页数据
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT id, key, name, remark, created_at
|
||||
FROM sys_dict
|
||||
WHERE (
|
||||
%s = ''
|
||||
OR key ILIKE '%%' || %s || '%%'
|
||||
OR name ILIKE '%%' || %s || '%%'
|
||||
)
|
||||
ORDER BY created_at DESC
|
||||
LIMIT %s OFFSET %s
|
||||
""",
|
||||
(keyword, keyword, keyword, page_size, offset),
|
||||
)
|
||||
|
||||
rows = cursor.fetchall()
|
||||
|
||||
result = []
|
||||
for row in rows:
|
||||
result.append(
|
||||
{
|
||||
"id": row[0],
|
||||
"key": row[1],
|
||||
"name": row[2],
|
||||
"remark": row[3],
|
||||
"created_at": MyUtils.format_datetime(row[4]),
|
||||
}
|
||||
)
|
||||
|
||||
return total, result
|
||||
|
||||
|
||||
def db_create_dict(key: str, name: str, remark: str):
|
||||
"""
|
||||
在数据库中创建字典
|
||||
"""
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO sys_dict (id, key, name, remark, created_at)
|
||||
VALUES (gen_random_uuid(), %s, %s, %s, now())
|
||||
RETURNING id
|
||||
""",
|
||||
(key, name, remark),
|
||||
)
|
||||
new_id = cursor.fetchone()[0]
|
||||
return new_id
|
||||
|
||||
|
||||
def db_update_dict(id: str, key: str, name: str, remark: str):
|
||||
"""
|
||||
在数据库中更新字典
|
||||
"""
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE sys_dict
|
||||
SET key=%s, name=%s, remark=%s
|
||||
WHERE id=%s
|
||||
""",
|
||||
(key, name, remark, id),
|
||||
)
|
||||
return id
|
||||
|
||||
|
||||
def db_delete_dict(id: str):
|
||||
"""
|
||||
在数据库中删除字典
|
||||
"""
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("DELETE FROM sys_dict WHERE id=%s", (id,))
|
||||
return id
|
||||
|
||||
|
||||
def db_get_dict_detail(dict_id: str):
|
||||
"""
|
||||
获取字典详情列表
|
||||
"""
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT id, value, sort, pid, dict_id, remark, created_at, updated_at
|
||||
FROM sys_dict_detail
|
||||
WHERE dict_id=%s
|
||||
ORDER BY sort ASC, created_at ASC
|
||||
""",
|
||||
(dict_id,),
|
||||
)
|
||||
rows = cursor.fetchall()
|
||||
result = []
|
||||
for row in rows:
|
||||
result.append(
|
||||
{
|
||||
"id": row[0],
|
||||
"value": row[1],
|
||||
"sort": row[2],
|
||||
"pid": row[3],
|
||||
"dict_id": row[4],
|
||||
"remark": row[5],
|
||||
"created_at": row[6].isoformat() if row[6] else None,
|
||||
"updated_at": row[7].isoformat() if row[7] else None,
|
||||
}
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def db_create_dict_detail(
|
||||
value: str, dict_id: str, sort: int = 0, pid: str = None, remark: str = None
|
||||
):
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO sys_dict_detail (id, value, dict_id, sort, pid, remark, created_at)
|
||||
VALUES (gen_random_uuid(), %s, %s, %s, %s, %s, now())
|
||||
RETURNING id
|
||||
""",
|
||||
(value, dict_id, sort, pid, remark),
|
||||
)
|
||||
new_id = cursor.fetchone()[0]
|
||||
return new_id
|
||||
|
||||
|
||||
def db_update_dict_detail(
|
||||
id: str, value: str = None, sort: int = None, pid: str = None, remark: str = None
|
||||
):
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE sys_dict_detail
|
||||
SET value=COALESCE(%s, value),
|
||||
sort=COALESCE(%s, sort),
|
||||
pid=COALESCE(%s, pid),
|
||||
remark=COALESCE(%s, remark),
|
||||
updated_at=now()
|
||||
WHERE id=%s
|
||||
""",
|
||||
(value, sort, pid, remark, id),
|
||||
)
|
||||
return id
|
||||
|
||||
|
||||
def db_delete_dict_detail(id: str):
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("DELETE FROM sys_dict_detail WHERE id=%s", (id,))
|
||||
return id
|
||||
|
||||
|
||||
def get_dict_detail_list_by_key(dict_key: str):
|
||||
"""
|
||||
通过字典 key 获取字典明细列表
|
||||
"""
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
d.id,
|
||||
d.value,
|
||||
d.sort,
|
||||
d.pid,
|
||||
d.remark,
|
||||
d.created_at
|
||||
FROM sys_dict_detail d
|
||||
JOIN sys_dict s ON d.dict_id = s.id
|
||||
WHERE s.key = %s
|
||||
ORDER BY d.sort ASC, d.created_at ASC
|
||||
""",
|
||||
(dict_key,),
|
||||
)
|
||||
|
||||
rows = cursor.fetchall()
|
||||
|
||||
result = []
|
||||
for row in rows:
|
||||
result.append(
|
||||
{
|
||||
"id": row[0],
|
||||
"value": row[1],
|
||||
"sort": row[2],
|
||||
"pid": row[3],
|
||||
"remark": row[4],
|
||||
"created_at": MyUtils.format_datetime(row[5]),
|
||||
}
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_dept_ids_by_user_id(user_id: UUID) -> list:
|
||||
# 第一步:通过 user_id 查找其所属的 dept_id
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("SELECT dept_id FROM users WHERE id = %s", (user_id,))
|
||||
dept_id = cursor.fetchone()
|
||||
|
||||
if not dept_id:
|
||||
raise ValueError(
|
||||
f"User with id {user_id} not found or has no department."
|
||||
)
|
||||
|
||||
dept_id = dept_id[0]
|
||||
|
||||
# 第二步:通过 dept_id 获取所有下级部门的 dept_id
|
||||
cursor.execute(
|
||||
"""
|
||||
WITH RECURSIVE dept_hierarchy AS (
|
||||
SELECT id FROM sys_dept WHERE id = %s
|
||||
UNION
|
||||
SELECT d.id FROM sys_dept d
|
||||
INNER JOIN dept_hierarchy dh ON d.parent_id = dh.id
|
||||
)
|
||||
SELECT id FROM dept_hierarchy;
|
||||
""",
|
||||
(dept_id,),
|
||||
)
|
||||
dept_ids = [row[0] for row in cursor.fetchall()]
|
||||
|
||||
return dept_ids
|
||||
|
||||
|
||||
def get_dept_ids_by_user_id(user_id: UUID) -> list:
|
||||
# 第一步:通过 user_id 查找其所属的 dept_id
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("SELECT dept_id FROM users WHERE id = %s", (user_id,))
|
||||
dept_id = cursor.fetchone()
|
||||
|
||||
if not dept_id:
|
||||
raise ValueError(
|
||||
f"User with id {user_id} not found or has no department."
|
||||
)
|
||||
|
||||
dept_id = dept_id[0]
|
||||
|
||||
# 第二步:通过 dept_id 获取所有下级部门的 dept_id
|
||||
cursor.execute(
|
||||
"""
|
||||
WITH RECURSIVE dept_hierarchy AS (
|
||||
SELECT id FROM sys_dept WHERE id = %s
|
||||
UNION
|
||||
SELECT d.id FROM sys_dept d
|
||||
INNER JOIN dept_hierarchy dh ON d.parent_id = dh.id
|
||||
)
|
||||
SELECT id FROM dept_hierarchy;
|
||||
""",
|
||||
(dept_id,),
|
||||
)
|
||||
dept_ids = [row[0] for row in cursor.fetchall()]
|
||||
|
||||
return dept_ids
|
||||
|
||||
|
||||
def get_dept_id_by_user_id(user_id: UUID) -> list:
|
||||
# 第一步:通过 user_id 查找其所属的 dept_id
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("SELECT dept_id FROM users WHERE id = %s", (user_id,))
|
||||
dept_id = cursor.fetchone()
|
||||
dept_id = dept_id[0]
|
||||
return dept_id
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
from typing import List
|
||||
|
||||
from fastapi import WebSocket
|
||||
|
||||
|
||||
class ConnectionManager:
|
||||
def __init__(self):
|
||||
self.active_connections: List[WebSocket] = []
|
||||
self.lock = asyncio.Lock()
|
||||
|
||||
async def connect(self, websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
async with self.lock:
|
||||
self.active_connections.append(websocket)
|
||||
|
||||
async def disconnect(self, websocket: WebSocket):
|
||||
async with self.lock:
|
||||
if websocket in self.active_connections:
|
||||
self.active_connections.remove(websocket)
|
||||
|
||||
async def broadcast(self, message: dict):
|
||||
async with self.lock:
|
||||
for ws in self.active_connections:
|
||||
await ws.send_json(message)
|
||||
Reference in New Issue
Block a user