SCLP
This commit is contained in:
77
SCLP/routers/access_devices_0.py
Normal file
77
SCLP/routers/access_devices_0.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 通行设备界面控制逻辑
|
||||
"""
|
||||
from fastapi import APIRouter, Request, Header, Query
|
||||
|
||||
from models.devices import DevicesTable, AccessDevicesScope, BuildingDevicesScope
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/getAccessDevicesInfo", summary="获取通行设备信息")
|
||||
async def get_access_devices_info(request: Request,
|
||||
is_associated: bool = Query(...),
|
||||
device_name: str = Query(None),
|
||||
product_name: str = Query(None),
|
||||
device_mac: str = Query(None),
|
||||
device_id: int = Query(None),
|
||||
token: str = Header(...)):
|
||||
"""获取通行设备信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
if device_name:
|
||||
resp = DevicesTable.get_access_devices_info(th, is_associated, device_name=device_name)
|
||||
elif product_name:
|
||||
resp = DevicesTable.get_access_devices_info(th, is_associated, product_name=product_name)
|
||||
elif device_mac:
|
||||
resp = DevicesTable.get_access_devices_info(th, is_associated, device_mac=device_mac)
|
||||
elif device_id:
|
||||
resp = DevicesTable.get_access_devices_info(th, is_associated, device_id=device_id)
|
||||
else:
|
||||
resp = DevicesTable.get_access_devices_info(th, is_associated)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/addAccessDevicesAssociateInfo", summary="批量增加大门门禁/大门闸机关联信息")
|
||||
async def add_access_devices_associate_info(request: Request, item: AccessDevicesScope, token: str = Header(...)):
|
||||
"""批量增加大门门禁/大门闸机关联信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
_callback = DevicesTable.add_access_devices(th, item.device_type, item.info)
|
||||
resp = {"status": _callback}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/addBuildingDevicesAssociateInfo", summary="批量增加楼栋门禁关联信息")
|
||||
async def add_building_devices_associate_info(request: Request, item: BuildingDevicesScope, token: str = Header(...)):
|
||||
"""批量增加楼栋门禁关联信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
_callback = DevicesTable.add_building_devices(th, "楼栋门禁", item.info)
|
||||
resp = {"status": _callback}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.delete("/deleteAssociatedAccessDeviceInfo", summary="移除完成关联的设备及其已授权的人员信息")
|
||||
async def delete_access_device_info(request: Request, device_id: int = Query(alias="id"), token: str = Header(...)):
|
||||
"""移除完成关联的设备及其已授权的人员信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = DevicesTable.delete_access_device_info(th, device_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
193
SCLP/routers/access_devices_1.py
Normal file
193
SCLP/routers/access_devices_1.py
Normal file
@@ -0,0 +1,193 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 通行授权界面控制逻辑
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
|
||||
from fastapi import APIRouter, Request, Header, File, UploadFile, Query
|
||||
|
||||
from config import PREFIX_PATH, SUB_PATH
|
||||
from config import APP_HOST as HOST_IP
|
||||
from config import IMAGE_SERVER_PORT as PORT
|
||||
from models.devices import SearchDevicesInfo, DevicesTable
|
||||
from models.householders import HouseholdersTable, GetAuthHouseholdersInfo, GetAuthUsersInfo, \
|
||||
UpdateHouseholderFace, AddAuthUserInfo, UpdateAuthUserInfo
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/getHouseholdersInfo", summary="授权住户查询")
|
||||
async def get_householders_info(request: Request,
|
||||
page: int = Query(..., gt=0),
|
||||
limit: int = Query(..., gt=0),
|
||||
token: str = Header(...)):
|
||||
"""获取已授权的住户信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_auth_householder_info(th, None, None, None, None,
|
||||
page, limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/getHouseholdersInfo", summary="授权住户条件查询")
|
||||
async def get_householders_info_by_condition(request: Request,
|
||||
item: GetAuthHouseholdersInfo,
|
||||
token: str = Header(...)):
|
||||
"""根据条件获取已授权的住户信息查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
logger.Logger.debug(f"{request.url.path} <- {item.__dict__}")
|
||||
resp = HouseholdersTable.get_auth_householder_info(th, item.search_type, item.search_key,
|
||||
item.space_type, item.space_id,
|
||||
item.page, item.limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getHouseholderDetailInfo", summary="住户授权详细信息查询")
|
||||
async def get_householder_detail_info(request: Request, householder_id: int = Query(...), token: str = Header(...)):
|
||||
"""获取指定住户授权详细信息查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_auth_householder_detail_info(th, householder_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getUsersInfo", summary="通用授权人员信息查询")
|
||||
async def get_users_info(request: Request,
|
||||
page: int = Query(..., gt=0),
|
||||
limit: int = Query(..., gt=0),
|
||||
token: str = Header(...)):
|
||||
"""获取已授权的通用人员信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_auth_users_info(th, None, None, None, page, limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/getUsersInfo", summary="通用授权人员信息条件查询")
|
||||
async def get_users_info_by_condition(request: Request,
|
||||
item: GetAuthUsersInfo,
|
||||
token: str = Header(...)):
|
||||
"""根据条件获取已授权的通用人员信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_auth_users_info(th, item.search_type, item.search_key,
|
||||
item.user_type, item.page, item.limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getUserDetailInfo", summary="通用授权人员详细信息查询")
|
||||
async def get_user_detail_info(request: Request,
|
||||
user_id: int = Query(alias="id"),
|
||||
token: str = Header(...)):
|
||||
"""获取指定通用人员的详细信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_auth_user_info(th, user_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.delete("/deleteUserInfo", summary="删除通用授权人员信息及关联设备授权")
|
||||
async def get_users_info(request: Request, user_id: int = Query(...), token: str = Header(...)):
|
||||
"""通用授权人员删除 & 移除关联设备授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.delete_auth_user_info(th, user_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/addUserInfo", summary="新增通用授权人员信息及关联设备授权")
|
||||
async def add_user_info(request: Request, item: AddAuthUserInfo, token: str = Header(...)):
|
||||
"""新增通用授权人员 & 人脸图像绑定 & 添加关联设备授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.add_auth_user_info(th, item)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/updateUserInfo", summary="更新通用授权人员信息及关联设备授权")
|
||||
async def update_user_info(request: Request, item: UpdateAuthUserInfo, token: str = Header(...)):
|
||||
"""更新通用授权人员信息 & 人脸图像绑定 & 判断是否需要刷新关联设备授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.update_auth_user_info(th, item)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/uploadHouseholderFace", summary="人脸图片上传")
|
||||
async def upload_householder_face(request: Request,
|
||||
face_file: UploadFile = File(...),
|
||||
token: str = Header(...)):
|
||||
"""接收人脸图片上传并保存"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
# 检查文件类型是否为图像
|
||||
if not face_file.content_type.startswith("image"):
|
||||
resp = {"status": False, "message": "仅支持上传图片"}
|
||||
else:
|
||||
file_content = await face_file.read()
|
||||
max_size_mb = 10 # 设置最大允许的文件大小为 10MB
|
||||
if face_file.file.seek(0, os.SEEK_END) > max_size_mb * 1024 * 1024:
|
||||
resp = {"status": False, "message": f"文件大小不得超过 {max_size_mb}MB"}
|
||||
else:
|
||||
save_path = f"./data/FaceImages"
|
||||
filename = f"_{int(time.time() * 1000)}"
|
||||
if not os.path.exists(save_path):
|
||||
os.mkdir(save_path)
|
||||
file_path = f"{save_path}/{filename}.jpg"
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(file_content)
|
||||
|
||||
# 返回成功消息及人脸照片的 URL
|
||||
face_url = f"http://{HOST_IP}:{PORT}{PREFIX_PATH}/{SUB_PATH}/{filename}.jpg"
|
||||
resp = {"face_url": face_url}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/updateHouseholderFace", summary="更新住户人脸信息")
|
||||
async def get_users_info(request: Request, item: UpdateHouseholderFace, token: str = Header(...)):
|
||||
"""人脸图像与住户ID绑定 & 刷新关联设备授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.update_householder_face(th, item.id, item.face_url)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/getAssociatedAccessDevicesInfo", summary="通用授权-门禁设备条件查询")
|
||||
async def get_associated_access_devices_info(request: Request, item: SearchDevicesInfo, token: str = Header(...)):
|
||||
"""已具备关联空间信息的门禁设备条件查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = DevicesTable.get_associated_access_devices_info(th, item.search_type, item.search_key)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
30
SCLP/routers/devices_manage.py
Normal file
30
SCLP/routers/devices_manage.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Created :
|
||||
@Updated :
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 设备管理界面控制逻辑
|
||||
"""
|
||||
from fastapi import APIRouter, Request, Header
|
||||
|
||||
from models.devices import DevicesTable
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/getAllDevicesInfo", summary="获取全量的设备信息")
|
||||
async def get_all_devices_info(request: Request, token: str = Header(...)):
|
||||
"""获取全量的设备信息列表"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
devices_info = DevicesTable.get_devices_info(th)
|
||||
resp = {"devices": devices_info}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
163
SCLP/routers/edge_simulation_api.py
Normal file
163
SCLP/routers/edge_simulation_api.py
Normal file
@@ -0,0 +1,163 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 模拟边缘对接所需的平台api接口
|
||||
"""
|
||||
from fastapi import APIRouter, Request, Query
|
||||
|
||||
from models.householders import HouseholdersTable
|
||||
from models.houses import HousesTable
|
||||
from models.spaces import SpacesTable
|
||||
from models.subsystem import SubsystemTable, HouseDetailInfo
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException, snake2camel_list_dict
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/v2/accesskey_auth", summary="回传一个无效的随机字符串")
|
||||
async def access_key_auth(_item: dict):
|
||||
return {"access_token": "Q0E5QjU4QUNDMDA4MTY4RDNFNkRGRjNGNzQ4NDAzMTQ5OTVBMDQwODMyNjBFMjBCQkIwQjA2QzlCNUQ3MUY3NA=="}
|
||||
|
||||
|
||||
@router.get("/v3/realty-master-data/owners/{user_id}", summary="根据用户 id 获取房产信息")
|
||||
async def get_property_info_by_user_id(request: Request, user_id: int):
|
||||
logger.Logger.debug(f"{request.url.path} <- {user_id}")
|
||||
th = get_table_handler()
|
||||
house_ids = HouseholdersTable.get_room_ids(th, user_id)
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"house_ids": house_ids
|
||||
},
|
||||
"code": 200,
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/v3/realty-master-data/houses", summary="根据房产 id 获取房产详细信息")
|
||||
async def get_house_detail_info(request: Request, item: dict):
|
||||
try:
|
||||
logger.Logger.debug(f"{request.url.path} <- {item}")
|
||||
house_ids = item["query"]["id"]["$in"]
|
||||
house_detail_list = []
|
||||
th = get_table_handler()
|
||||
for house_id in house_ids:
|
||||
house_detail_info = HousesTable.get_house_detail_info(th, house_id)
|
||||
if house_detail_info is not None:
|
||||
house_detail_list.append(house_detail_info)
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"total_count": len(house_detail_list),
|
||||
"total_page": 0,
|
||||
"list": house_detail_list
|
||||
},
|
||||
"code": 200,
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
except (KeyError, TypeError):
|
||||
raise InvalidException("请求参数结构异常")
|
||||
|
||||
|
||||
@router.post("/v2/realty-master-data/SubsystemSpaceMap/list", summary="查找空间结构中的房间信息")
|
||||
async def get_subsystem_house_detail_info(request: Request, item: dict):
|
||||
try:
|
||||
logger.Logger.debug(f"{request.url.path} <- {item}")
|
||||
project_id = item["query"]["project_id"]["$eq"]
|
||||
th = get_table_handler()
|
||||
data_list = SubsystemTable.get_house_detail_info_by_project_id(th, project_id)
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"total_count": len(data_list),
|
||||
"total_page": 0,
|
||||
"list": data_list
|
||||
},
|
||||
"code": 200,
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} -> {resp}")
|
||||
return resp
|
||||
except (KeyError, TypeError):
|
||||
raise InvalidException("请求参数结构异常")
|
||||
|
||||
|
||||
@router.post("/v2/realty-master-data/SubsystemSpaceMap/added", summary="添加房产信息")
|
||||
async def add_subsystem_house_info(request: Request, item: HouseDetailInfo):
|
||||
try:
|
||||
logger.Logger.debug(f"{request.url.path} <- {item}")
|
||||
th = get_table_handler()
|
||||
SubsystemTable.add_sub_system_house_info(th, item)
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": item.message_id,
|
||||
"code": 200,
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
except (KeyError, TypeError):
|
||||
raise InvalidException("请求参数结构异常")
|
||||
|
||||
|
||||
@router.post("/v2/realty-master-data/SubsystemSpaceMap/update", summary="更新房产信息")
|
||||
async def update_subsystem_house_info(request: Request, item: HouseDetailInfo):
|
||||
try:
|
||||
logger.Logger.debug(f"{request.url.path} <- {item}")
|
||||
th = get_table_handler()
|
||||
item.action = "update"
|
||||
SubsystemTable.add_sub_system_house_info(th, item)
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": item.message_id,
|
||||
"code": 200,
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
except (KeyError, TypeError):
|
||||
raise InvalidException("请求参数结构异常")
|
||||
|
||||
|
||||
@router.post("/v2/smart-access/house/house_ty_maps", summary="查询房产的真实信息")
|
||||
async def get_house_ty_info(request: Request, item: dict):
|
||||
try:
|
||||
logger.Logger.debug(f"{request.url.path} <- {item}")
|
||||
project_id = item["query"]["project_id"]["$eq"]
|
||||
room_id = item["query"]["_id"]["$eq"]
|
||||
th = get_table_handler()
|
||||
house_ty_info = HousesTable.get_house_ty_info(th, project_id, room_id)
|
||||
if house_ty_info is None:
|
||||
house_ty_infos = []
|
||||
else:
|
||||
house_ty_infos = [house_ty_info]
|
||||
resp = {
|
||||
"status": 200,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"count": 1,
|
||||
"list": house_ty_infos,
|
||||
"query_res": {
|
||||
"count": 1,
|
||||
"list": snake2camel_list_dict(house_ty_infos)
|
||||
}
|
||||
},
|
||||
"det": 0
|
||||
}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
except (KeyError, TypeError):
|
||||
raise InvalidException("请求参数结构异常")
|
||||
84
SCLP/routers/householder_manage.py
Normal file
84
SCLP/routers/householder_manage.py
Normal file
@@ -0,0 +1,84 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 住户管理界面控制逻辑
|
||||
"""
|
||||
from fastapi import APIRouter, Request, Header, Query
|
||||
|
||||
from models.householders import HouseholdersTable, GetHouseholdersInfo, AddHouseholderInfo, UpdateHouseholderInfo
|
||||
from models.houses import HousesTable
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/addHouseholderInfo", summary="新增住户信息")
|
||||
async def add_householder_info(request: Request, item: AddHouseholderInfo, token: str = Header(...)):
|
||||
"""新增住户信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
# 进行住户信息插入
|
||||
householder_id = HouseholdersTable.insert(th, item.name, item.sex, item.phone, "住户")
|
||||
if householder_id:
|
||||
for room_id, _type in item.property_info:
|
||||
# 房产关联表信息插入
|
||||
HouseholdersTable.insert_type(th, room_id, householder_id, _type)
|
||||
# 更新房产中的住户数量
|
||||
old_count = HousesTable.get_householder_count(th, room_id)
|
||||
HousesTable.update_householder_count(th, room_id, old_count + 1)
|
||||
resp = {"status": True}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/getHouseholderInfo", summary="获取住户信息")
|
||||
async def get_householder_info(request: Request, item: GetHouseholdersInfo, token: str = Header(...)):
|
||||
"""获取住户信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_householder_info(th, item.search_type, item.search_key, item.role_type,
|
||||
item.page, item.limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getHouseholderInfo", summary="查询指定住户信息")
|
||||
async def get_householder_detail_info(request: Request,
|
||||
householder_id: int = Query(alias="id"),
|
||||
token: str = Header(...)):
|
||||
"""查询指定住户信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.get_householder_info_by_id(th, householder_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/updateHouseholderInfo", summary="更新指定住户信息")
|
||||
async def update_householder_info(request: Request, item: UpdateHouseholderInfo, token: str = Header(...)):
|
||||
"""更新指定住户信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.update_householder_info(th, item.householder_id, item.property_info)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.delete("/deleteHouseholderInfo", summary="删除指定住户信息及移除其关联设备授权")
|
||||
async def delete_householder_info(request: Request, householder_id: int = Query(alias="id"), token: str = Header(...)):
|
||||
"""删除指定住户的信息及其关联授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = HouseholdersTable.delete_householder_info(th, householder_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
86
SCLP/routers/houses_manage.py
Normal file
86
SCLP/routers/houses_manage.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 房产信息控制逻辑
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Header, Request, Query
|
||||
from pydantic import BaseModel, field_validator, Field
|
||||
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from models.houses import HousesTable
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class ListsReq(BaseModel):
|
||||
project: str = Field(description="必填项,用于限定项目编号")
|
||||
area: Optional[str] = Field(None, description="可选项,用于限定区域")
|
||||
building: Optional[str] = Field(None, description="可选项,用于限定楼栋")
|
||||
unit: Optional[str] = Field(None, description="可选项,用于限定单元")
|
||||
floor: Optional[str] = Field(None, description="可选项,用于限定楼层")
|
||||
target: str = Field(description="必填项,用于控制输出结果,取值范围:area, building, unit, floor, room")
|
||||
|
||||
def dict(self, *args, **kwargs):
|
||||
_dict = self.__dict__.copy()
|
||||
for key, value in self.__dict__.items():
|
||||
if value is None:
|
||||
_dict.pop(key)
|
||||
_dict.pop("target")
|
||||
return _dict
|
||||
|
||||
@field_validator("target")
|
||||
def validate_target(cls, value):
|
||||
if value not in ["area", "building", "unit", "floor", "room"]:
|
||||
raise InvalidException("请提供正确的请求target [area, building, unit, floor, room]")
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
@router.get("/projects", summary="获取所有项目列表")
|
||||
async def get_projects_list(request: Request, token: str = Header(...)):
|
||||
"""获取项目列表"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
projects_list = HousesTable.get_items_by_dynamic_item(th, "project", {})
|
||||
resp = {"projects": projects_list}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/project/lists", summary="动态获取房产信息")
|
||||
async def get_items(request: Request,
|
||||
item: ListsReq,
|
||||
token: str = Header(...)):
|
||||
"""根据请求获取列表"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
item_list = HousesTable.get_items_by_dynamic_item(th, item.target, item.dict())
|
||||
resp = {f"{item.target.split('_')[0]}s": item_list}
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getHouseholderCount", summary="获取房产住户数量")
|
||||
async def get_householder_count(request: Request,
|
||||
room_id: str = Query(...),
|
||||
token: str = Header(...)):
|
||||
"""根据请求获取对应房屋中当前住户数量"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
count = HousesTable.get_householder_count(th, room_id)
|
||||
if count is not None:
|
||||
resp = {"count": count}
|
||||
else:
|
||||
raise InvalidException("room_id 不存在")
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
140
SCLP/routers/login.py
Normal file
140
SCLP/routers/login.py
Normal file
@@ -0,0 +1,140 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 登陆界面控制逻辑
|
||||
"""
|
||||
import hashlib
|
||||
import os.path
|
||||
import random
|
||||
import io
|
||||
import time
|
||||
from typing import Optional
|
||||
from starlette.responses import StreamingResponse
|
||||
|
||||
from pydantic import BaseModel
|
||||
from fastapi import APIRouter, Query, Request
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils.database import get_table_handler
|
||||
from utils import logger
|
||||
from utils.misc import generate_captcha_text
|
||||
from models.sessions import SessionsTable
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class LoginItem(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
session_id: str
|
||||
captcha: str
|
||||
|
||||
|
||||
class LoginResp(BaseModel):
|
||||
status: bool
|
||||
message: str
|
||||
token: Optional[str] = None
|
||||
|
||||
|
||||
def generate_captcha_image(text, size=(120, 40), font_path='./data/mvboli.ttf', font_size=24):
|
||||
"""生成验证码图片"""
|
||||
image = Image.new('RGB', size, (73, 109, 137)) # 设置背景色
|
||||
d = ImageDraw.Draw(image)
|
||||
assert os.path.exists(font_path), "字体文件不存在"
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
# d.text((5, 5), text, font=font, fill=(255, 255, 0)) # 设置字体颜色和位置
|
||||
font_box = font.getbbox(text)
|
||||
text_width, text_height = font_box[2] - font_box[0], font_box[3] - font_box[1]
|
||||
text_x = (size[0] - text_width) // 2
|
||||
text_y = (size[1] - text_height) // 2
|
||||
d.text((text_x, text_y - 8), text, font=font, fill=(255, 255, 0))
|
||||
|
||||
# 添加噪点
|
||||
for _ in range(100): # 可以根据需要调整噪点数量
|
||||
x = random.randint(0, size[0] - 1)
|
||||
y = random.randint(0, size[1] - 1)
|
||||
image.putpixel((x, y), (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
|
||||
|
||||
# 添加线条
|
||||
for _ in range(3): # 可以根据需要调整线条数量
|
||||
x1, y1 = random.randint(0, size[0] - 1), random.randint(0, size[1] - 1)
|
||||
x2, y2 = random.randint(0, size[0] - 1), random.randint(0, size[1] - 1)
|
||||
d.line([(x1, y1), (x2, y2)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
|
||||
width=2)
|
||||
|
||||
# 将图片保存为字节流
|
||||
bytes_io = io.BytesIO()
|
||||
image.save(bytes_io, format='PNG')
|
||||
# image.save("./data/tmp.png", format='PNG')
|
||||
bytes_io.seek(0)
|
||||
return bytes_io
|
||||
|
||||
|
||||
def hash_password(password):
|
||||
"""对密码进行 SHA-256 哈希加密"""
|
||||
password_bytes = password.encode('utf-8')
|
||||
sha256_hash = hashlib.sha256()
|
||||
sha256_hash.update(password_bytes)
|
||||
return sha256_hash.hexdigest()
|
||||
|
||||
|
||||
def verify_password(password, hashed_password):
|
||||
"""比对密码和哈希值"""
|
||||
password_hash = hash_password(password)
|
||||
return password_hash.lower() == hashed_password.lower()
|
||||
|
||||
|
||||
def authenticate_token(token: str):
|
||||
th = get_table_handler()
|
||||
timeout_timestamp = str(int(time.time() * 1000 - 4 * 60 * 60 * 1000))
|
||||
return SessionsTable.check_token(th, timeout_timestamp, token)
|
||||
|
||||
|
||||
@router.get("/generateCaptcha", summary="生成验证码")
|
||||
async def generate_captcha_endpoint(request: Request,
|
||||
session_id: str = Query(None, description="Session ID")):
|
||||
"""生成验证码图片并返回"""
|
||||
if session_id:
|
||||
captcha_text = generate_captcha_text()
|
||||
logger.Logger.debug(f"{request.url.path} 验证码生成:{captcha_text}")
|
||||
# session_id 入库
|
||||
th = get_table_handler()
|
||||
SessionsTable.insert(th, session_id, captcha_text)
|
||||
captcha_image = generate_captcha_image(captcha_text)
|
||||
# 设置HTTP响应的头部,指定内容类型为PNG图片
|
||||
headers = {"Content-Type": "image/png"}
|
||||
return StreamingResponse(captcha_image, headers=headers)
|
||||
else:
|
||||
logger.Logger.error(f"{request.url.path} 请求参数缺少 session_id - {request.client.host}")
|
||||
return {"status": False, "message": "请求参数缺少 session_id"}
|
||||
|
||||
|
||||
@router.post("/login", response_model=LoginResp, response_model_exclude_none=True, summary="登录请求")
|
||||
async def login(item: LoginItem):
|
||||
"""简单的账户登录逻辑"""
|
||||
status = False
|
||||
token = None
|
||||
th = get_table_handler()
|
||||
# 验证码校验
|
||||
right_captcha = SessionsTable.get_captcha(th, item.session_id)
|
||||
if right_captcha is not None:
|
||||
if item.captcha.lower() == right_captcha.lower():
|
||||
# 账户密码校验
|
||||
if item.username == "admin":
|
||||
if verify_password(item.password, "B12AD23C7E230E2CA365508DD16635DD3D7214BCD9BEA27457A356FD5C15F8BF"):
|
||||
status = True
|
||||
message = "校验通过"
|
||||
token = generate_captcha_text(16)
|
||||
SessionsTable.update(th, item.session_id, item.username, token)
|
||||
else:
|
||||
message = "密码错误"
|
||||
else:
|
||||
message = "账户不存在"
|
||||
else:
|
||||
message = "验证码错误"
|
||||
else:
|
||||
message = "无效 session_id"
|
||||
resp = LoginResp(status=status, message=message, token=token)
|
||||
logger.Logger.debug("/login " + str(resp.__dict__))
|
||||
return resp
|
||||
85
SCLP/routers/parkinglot_0.py
Normal file
85
SCLP/routers/parkinglot_0.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 车场管理界面控制逻辑
|
||||
"""
|
||||
from fastapi import APIRouter, Request, Header, Query
|
||||
|
||||
from models.parkinglots import ParkinglotsTable, AddParkingLot
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/getParkingLotsInfo", summary="车场信息查询")
|
||||
async def get_parkinglots_info(request: Request, token: str = Header(...)):
|
||||
"""获取车场信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_parkinglots_info(th)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/addParkingLot", summary="添加车场")
|
||||
async def add_parkinglot(request: Request, item: AddParkingLot, token: str = Header(...)):
|
||||
"""添加显示信息的车场 & 更新车场编号对应的名字和供应商"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
factory_name = item.factory_name if item.factory_name else ''
|
||||
resp = ParkinglotsTable.update_parkinglot_show(th, item.parkinglot_number, item.parkinglot_name, factory_name, True)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.delete("/deleteParkingLot", summary="移除车场")
|
||||
async def delete_parkinglot(request: Request,
|
||||
parkinglot_number: str = Query(alias="number", description="车场编号"),
|
||||
token: str = Header(...)):
|
||||
"""移除显示信息的车场"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.update_parkinglot_show(th, parkinglot_number, None, None, False)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getParkingLotsAreaInfo", summary="区域信息查询")
|
||||
async def get_parkinglots_area_info(request: Request, token: str = Header(...)):
|
||||
"""区域信息查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_showed_parkinglot_area_info(th)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getParkingLotsChannelInfo", summary="通道信息查询")
|
||||
async def get_parkinglots_channel_info(request: Request, token: str = Header(...)):
|
||||
"""通道信息查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_showed_parkinglot_channel_info(th)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getParkingLotsGateInfo", summary="道闸信息查询")
|
||||
async def get_parkinglots_channel_info(request: Request, token: str = Header(...)):
|
||||
"""道闸信息查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_showed_parkinglot_gate_info(th)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
108
SCLP/routers/parkinglot_1.py
Normal file
108
SCLP/routers/parkinglot_1.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 车辆授权界面控制逻辑
|
||||
"""
|
||||
from fastapi import APIRouter, Query, Request, Header
|
||||
|
||||
from models.parkinglots import ParkinglotsTable, GetCarsInfo, AddCarsCard, UpdateCarsCard
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/getCarsInfo", summary="授权车辆信息查询")
|
||||
async def get_cars_info(request: Request,
|
||||
page: int = Query(None),
|
||||
limit: int = Query(None),
|
||||
token: str = Header(...)):
|
||||
"""授权车辆信息全量查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_cars_info(th, None, None, page, limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/getCarsInfo", summary="授权车辆信息条件查询")
|
||||
async def get_cars_info(request: Request,
|
||||
item: GetCarsInfo,
|
||||
token: str = Header(...)):
|
||||
"""授权车辆信息全量查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_cars_info(th, item.search_type, item.search_key, item.page, item.limit)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getCarDetailInfo", summary="详细授权信息查询")
|
||||
async def get_car_detail_info(request: Request,
|
||||
auth_id: int = Query(...),
|
||||
token: str = Header(...)):
|
||||
"""授权车辆信息全量查询"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_auth_info(th, auth_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getCarIdAuthStatus", summary="获取车牌号授权状态")
|
||||
async def get_car_id_auth_status(request: Request,
|
||||
car_id: str = Query(...),
|
||||
token: str = Header(...)):
|
||||
"""获取车牌号授权状态"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.get_car_id_auth_status(th, car_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.delete("/deleteCarAuthId", summary="删除车辆授权")
|
||||
async def delete_car_auth_id(request: Request,
|
||||
auth_id: int = Query(...),
|
||||
token: str = Header(...)):
|
||||
"""删除车辆月卡授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.delete_car_auth_id(th, auth_id)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/addCarAuthInfo", summary="新增车辆授权")
|
||||
async def add_car_card_auth(request: Request,
|
||||
item: AddCarsCard,
|
||||
token: str = Header(...)):
|
||||
"""新增车辆月卡授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.add_car_card_auth(th, item)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/updateCarInfo", summary="更新车辆授权")
|
||||
async def add_car_card_auth(request: Request,
|
||||
item: UpdateCarsCard,
|
||||
token: str = Header(...)):
|
||||
"""更新车辆月卡授权"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = ParkinglotsTable.update_car_card_auth(th, item)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
101
SCLP/routers/space_manage.py
Normal file
101
SCLP/routers/space_manage.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
@Author : xuxingchen
|
||||
@Contact : xuxingchen@sinochem.com
|
||||
@Desc : 通行空间映射界面控制逻辑
|
||||
"""
|
||||
import os.path
|
||||
from io import BytesIO
|
||||
|
||||
from fastapi import APIRouter, Request, Header, BackgroundTasks, UploadFile, File
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from models.brands import BrandsTable, UpdateBrand
|
||||
from models.spaces import SpacesTable
|
||||
from routers.login import authenticate_token
|
||||
from utils import logger
|
||||
from utils.logger import TOKEN_ERROR
|
||||
from utils.database import get_table_handler
|
||||
from utils.misc import InvalidException, valid_xls
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/updateSubSystemPlatformName", summary="更新当前使用的可视对讲厂家")
|
||||
async def update_sub_system_platform_name(request: Request, item: UpdateBrand, token: str = Header(...)):
|
||||
"""更新当前使用的可视对讲厂家"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = BrandsTable.update_checked_factory(th, item.name)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/getSubSystemPlatformName", summary="查询当前使用的可视对讲厂家")
|
||||
async def get_sub_system_platform_name(request: Request, token: str = Header(...)):
|
||||
"""获取当前启用的可视对讲厂家"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
resp = BrandsTable.get_checked_factory(th)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
|
||||
|
||||
@router.get("/exportAiotPlatformData", summary="导出AIOT平台空间数据")
|
||||
async def export_aiot_platform_data(request: Request, background_tasks: BackgroundTasks, token: str = Header(...)):
|
||||
"""导出AIOT平台空间数据"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
file_path = SpacesTable.get_aiot_platform_data(th)
|
||||
background_tasks.add_task(os.remove, file_path)
|
||||
logger.Logger.debug(f"{request.url.path} 完成AIOT平台空间数据导出")
|
||||
return FileResponse(path=file_path,
|
||||
filename=os.path.basename(file_path),
|
||||
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
|
||||
|
||||
@router.get("/exportSubSystemData", summary="导出子系统空间结构数据表")
|
||||
async def export_aiot_platform_data(request: Request, background_tasks: BackgroundTasks, token: str = Header(...)):
|
||||
"""导出子系统空间结构数据表"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
th = get_table_handler()
|
||||
file_path = SpacesTable.get_sub_system_data(th)
|
||||
background_tasks.add_task(os.remove, file_path)
|
||||
logger.Logger.debug(f"{request.url.path} 完成子系统空间数据导出")
|
||||
return FileResponse(path=file_path,
|
||||
filename=os.path.basename(file_path),
|
||||
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
|
||||
|
||||
@router.post("/importIdMapData", summary="导入空间映射表")
|
||||
async def import_id_map_data(request: Request,
|
||||
xls_file: UploadFile = File(...),
|
||||
token: str = Header(...)):
|
||||
"""接收空间映射表xls表格上传、校验并更新对应映射信息"""
|
||||
if not authenticate_token(token):
|
||||
raise InvalidException(TOKEN_ERROR)
|
||||
# 检查文件类型是否为xls
|
||||
if xls_file.content_type not in ["application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]:
|
||||
resp = {"status": False, "message": "仅支持上传xls文件"}
|
||||
else:
|
||||
file_content = await xls_file.read()
|
||||
max_size_mb = 10 # 设置最大允许的文件大小为 10MB
|
||||
if xls_file.file.seek(0, os.SEEK_END) > max_size_mb * 1024 * 1024:
|
||||
resp = {"status": False, "message": f"文件大小不得超过 {max_size_mb}MB"}
|
||||
else:
|
||||
# 解析xls,校验数据格式是否符合标准
|
||||
required_columns = ["房屋id", "子系统id", "子系统空间名称"]
|
||||
_callback, message, data = valid_xls(BytesIO(file_content), required_columns)
|
||||
if _callback:
|
||||
th = get_table_handler()
|
||||
SpacesTable.update(th, data)
|
||||
resp = {"status": True}
|
||||
else:
|
||||
raise InvalidException(message)
|
||||
logger.Logger.debug(f"{request.url.path} {resp}")
|
||||
return resp
|
||||
Reference in New Issue
Block a user