From 6b29a5ef765f71fd129054cad01484cd40a3a4ab Mon Sep 17 00:00:00 2001 From: haotian <2421912570@qq.com> Date: Wed, 4 Jun 2025 17:40:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0--=E6=B7=BB=E5=8A=A0=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9C=BA=E5=99=A8=E4=BA=BA=E4=BF=A1=E6=81=AF=E6=9C=89?= =?UTF-8?q?=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/endpoints/events.py | 88 ++++++++++++++++++++++++- app/core/config.py | 8 +-- app/crud/event.py | 14 +++- app/models/models.py | 114 +++++++++++++++++++-------------- app/schemas/event.py | 7 ++ 5 files changed, 174 insertions(+), 57 deletions(-) diff --git a/app/api/v1/endpoints/events.py b/app/api/v1/endpoints/events.py index cd70ab5..068e1cc 100644 --- a/app/api/v1/endpoints/events.py +++ b/app/api/v1/endpoints/events.py @@ -3,10 +3,12 @@ from fastapi import APIRouter, Depends, HTTPException, Query, Body from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.crud.event import event -from app.models.models import Robot, Message -from app.schemas.event import EventList, EventDetail, EventUpdate, EventQuery, BackStageEvent, BackStageEventDto, BackStageEventDetail, EditTemperatureDto, OcrAlertMessage, OcrAlertMessageDto +from app.models.models import Robot, Message, RobotInfo,Group, GroupRobot +from app.schemas.event import EventList, EventDetail, EventUpdate, EventQuery, BackStageEvent, BackStageEventDto, BackStageEventDetail, EditTemperatureDto, OcrAlertMessage, OcrAlertMessageDto, GetRobotDto from app.util.httpResponse import BaseResponse from app.util.status import EventType +from sqlalchemy import select +from app.services.robot_sync_service import robot_sync_service # import datetime @@ -106,6 +108,88 @@ async def delete_event( return BaseResponse(code=404,msg="事件不存在") return BaseResponse(code=200, msg="success", data=EventDetail.model_validate(event_obj)) +@router.post("/event/getRobotList", response_model=BaseResponse) +async def get_robot_list( + get_robot_dto: Optional[GetRobotDto] = Body(...), + db: AsyncSession = Depends(get_db) +): + """ + 获取机器人列表 + """ + try: + # 构建查询条件 + conditions = [] + if get_robot_dto.number: + conditions.append(Robot.number.like(f"%{get_robot_dto.number}%")) + if get_robot_dto.status: + conditions.append(Robot.status == get_robot_dto.status) + if get_robot_dto.onlineStatus: + conditions.append(Robot.onlineStatus == get_robot_dto.onlineStatus) + + # 查询机器人列表 + query = ( + select(Robot, RobotInfo, Group) + .outerjoin(RobotInfo, Robot.robotId == RobotInfo.robotId) + .outerjoin(GroupRobot, Robot.robotId == GroupRobot.robotId) + .outerjoin(Group, GroupRobot.groupingId == Group.groupingId) + ) + + if conditions: + query = query.where(*conditions) + + result = await db.execute(query) + robots = result.all() + + # 格式化返回数据 + robot_list = [] + for robot, robot_info, group in robots: + robot_dict = { + "robotId": robot.robotId, + "number": robot.number, + "groupingId": robot.groupingId, + "onlineStatus": robot.onlineStatus, + "status": robot.status, + "groupName": group.name if group else None, + "robotInfo": { + "temperature": robot_info.temperature if robot_info else None, + "humidity": robot_info.humidity if robot_info else None, + "power": robot_info.power if robot_info else None, + "mileage": robot_info.mileage if robot_info else None, + "area": robot_info.area if robot_info else None, + "floor": robot_info.floor if robot_info else None, + "map": robot_info.map if robot_info else None, + "positon": robot_info.positon if robot_info else None, + "status": robot_info.status if robot_info else None, + "ststusName": robot_info.ststusName if robot_info else None, + "updateTime": robot_info.updateTime if robot_info else None + } + } + robot_list.append(robot_dict) + + return BaseResponse(code=200, msg="success", data=robot_list) + + except Exception as e: + print(f"获取机器人列表失败: {str(e)}") + return BaseResponse(code=500, msg="获取机器人列表失败") + +@router.post("/event/refreshRobotList", response_model=BaseResponse) +async def refresh_robot_list( + db: AsyncSession = Depends(get_db) +): + """ + 刷新机器人列表 + """ + try: + # 手动触发数据同步 + success = await robot_sync_service.sync_robot_data(db) + if success: + return BaseResponse(code=200, msg="刷新成功") + return BaseResponse(code=500, msg="刷新失败") + + except Exception as e: + print(f"刷新机器人列表失败: {str(e)}") + return BaseResponse(code=500, msg="刷新失败") + # 获取未处理告警消息列表 @router.get("/events/messagesUnhandled", # response_model=BaseResponse[dict] diff --git a/app/core/config.py b/app/core/config.py index e6813de..c45f1ce 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -2,12 +2,12 @@ from pydantic_settings import BaseSettings class Settings(BaseSettings): # 数据库配置 - DB_HOST: str = "14.103.162.172" - # DB_HOST: str = "10.0.0.17" + # DB_HOST: str = "14.103.162.172" + DB_HOST: str = "10.0.0.17" DB_PORT: int = 3306 DB_USER: str = "root" - DB_PASSWORD: str = "dnxxkj" - # DB_PASSWORD: str = "root" + # DB_PASSWORD: str = "dnxxkj" + DB_PASSWORD: str = "root" DB_NAME: str = "kangda" # DB_NAME: str = "kangda_test" # 测试数据库 diff --git a/app/crud/event.py b/app/crud/event.py index f010e58..f6e05c9 100644 --- a/app/crud/event.py +++ b/app/crud/event.py @@ -4,11 +4,13 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from app.crud.base import CRUDBase from app.models.models import Event, Image, Temperature, Message, Robot -from app.schemas.event import EventUpdate, EventQuery, BackStageEvent, BackStageEventDto, BackStageEventDetail, EditTemperatureDto, OcrAlertMessage, OcrAlertMessageDto +from app.schemas.event import EventUpdate, EventQuery, BackStageEvent, BackStageEventDto, BackStageEventDetail, EditTemperatureDto, OcrAlertMessage, OcrAlertMessageDto, GetRobotDto from pydantic import VERSION as PYDANTIC_VERSION from datetime import datetime +# from app.util import kangda + class CRUDEvent(CRUDBase[Event, EventUpdate, EventUpdate]): async def get_by_id(self, db: AsyncSession, *, event_id: str) -> Optional[Event]: """根据ID获取事件""" @@ -414,7 +416,15 @@ class CRUDEvent(CRUDBase[Event, EventUpdate, EventUpdate]): return result.scalars() except Exception as e: print(f"{e}") - + + async def get_robot_list( + self, + db: AsyncSession, + get_robot_dto: GetRobotDto + ): + # 前端登录 + d = kangda._login_front() + duty_list = kangda._get_robot_group(d["tenantInfoId"], d["token"]) diff --git a/app/models/models.py b/app/models/models.py index 3f66236..42e2901 100644 --- a/app/models/models.py +++ b/app/models/models.py @@ -154,57 +154,73 @@ class Robot(Base): createTime = Column(DateTime, default=datetime.now, nullable=False, comment='创建时间') updateTime = Column(DateTime, default=datetime.now, nullable=False, comment='更新时间') - -# class RobotInfo(Base): -# __tablename__ = "robot_info" -# robotInfoId = Column() - -# hkStstusName = Column(String(20)) -# code = Column(String(5)) -# errorType = Column(String(5)) -# remoteControl = Column(String(5)) -# buttonStop = Column(String(5)) -# vertical = Column(String(5)) -# versionName = Column(String(50)) -# theta = Column(String(20)) -# speed = Column(String(5)) -# routeName = Column(String(20)) -# charingTaskStatus = Column(String(5)) -# socketType = Column(String(5)) -# horizontal = Column( String(5)) -# ststusName = Column(String(20)) -# enStstusName = Column(String(20)) -# aistatus = Column(String(5)) -# pm2_5 = Column(String(20)) -# temperature = Column(String(20)) -# humidity = Column(String(20)) -# power = Column(String(5)) -# floor = Column(String(5)) -# map = Column(String(20)) -# mileage = Column(String(5)) -# area = Column(String(5)) -# nextTaskTime = Column('nextTaskTime', String) -# address = Column('address', String) -# fromUserId = Column('fromUserId', String) -# ip = Column('ip', String) -# pm10 = Column('pm10', String) -# index = Column('index', String) # 使用引号避免关键字冲突 -# message = Column('message', String) -# robotId = Column('robotId', String) -# versionCode = Column('versionCode', String) -# videoStatus = Column('videoStatus', String) -# voltage = Column('voltage', String) -# focal = Column('focal', String) -# ststus = Column('ststus', String) -# positon = Column('positon', String) # 注意原始JSON中的拼写 -# robotType = Column('robotType', String) -# clearCharingTaskTime = Column('clearCharingTaskTime', String) -# cmd = Column('cmd', String) -# vehicleid = Column('vehicleid', String) -# device = Column('device', String) -# status = Column('status', String) + # info_records = relationship( + # "RobotInfo", + # back_populates="robot", + # cascade="all, delete-orphan" # 可选:级联删除关联记录 + # ) +class RobotInfo(Base): + __tablename__ = "robot_info" + + robotInfoId = Column(BigInteger, primary_key=True, autoincrement=True, comment='机器人信息ID') + robotId = Column(String(100), ForeignKey('robot.robotId', ondelete="CASCADE"), nullable=False, comment='关联机器人ID') + hkStstusName = Column(String(20), comment='香港状态名称') + code = Column(String(5), comment='状态码') + errorType = Column(String(5), comment='错误类型') + remoteControl = Column(String(5), comment='远程控制状态') + buttonStop = Column(String(5), comment='按钮停止状态') + vertical = Column(String(5), comment='垂直状态') + versionName = Column(String(50), comment='版本名称') + theta = Column(String(20), comment='角度') + speed = Column(String(5), comment='速度') + routeName = Column(String(20), comment='路线名称') + charingTaskStatus = Column(String(5), comment='充电任务状态') + socketType = Column(String(5), comment='插座类型') + horizontal = Column(String(5), comment='水平状态') + ststusName = Column(String(20), comment='状态名称') + enStstusName = Column(String(20), comment='英文状态名称') + aistatus = Column(String(5), comment='AI状态') + pm2_5 = Column(String(20), comment='PM2.5') + temperature = Column(String(20), comment='温度') + humidity = Column(String(20), comment='湿度') + power = Column(String(5), comment='电量') + floor = Column(String(5), comment='楼层') + map = Column(String(20), comment='地图') + mileage = Column(String(5), comment='里程') + area = Column(String(5), comment='区域') + nextTaskTime = Column(String(20), comment='下一个任务时间') + address = Column(String(500), comment='地址') + fromUserId = Column(String(100), comment='用户ID') + ip = Column(String(50), comment='IP地址') + pm10 = Column(String(20), comment='PM10') + index = Column(String(20), comment='索引') + message = Column(String(500), comment='消息') + versionCode = Column(String(50), comment='版本代码') + videoStatus = Column(String(5), comment='视频状态') + voltage = Column(String(20), comment='电压') + focal = Column(String(20), comment='焦距') + ststus = Column(String(5), comment='状态') + positon = Column(String(100), comment='位置') + robotType = Column(String(20), comment='机器人类型') + clearCharingTaskTime = Column(String(20), comment='清除充电任务时间') + cmd = Column(String(20), comment='命令') + vehicleid = Column(String(100), comment='车辆ID') + device = Column(String(100), comment='设备') + status = Column(String(5), comment='状态') + createTime = Column(DateTime, default=datetime.now, nullable=False, comment='创建时间') + updateTime = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间') + + # robot = relationship("Robot", back_populates="robot_info") + + __table_args__ = ( + Index('idx_robot_info_robot_id', 'robotId'), + Index('idx_robot_info_create_time', 'createTime'), + Index('idx_robot_info_update_time', 'updateTime'), + ) + + class Group(Base): __tablename__ = "group" groupingId = Column(String(100), primary_key=True, comment="分组id") diff --git a/app/schemas/event.py b/app/schemas/event.py index 3f953f2..26bd2d4 100644 --- a/app/schemas/event.py +++ b/app/schemas/event.py @@ -2,6 +2,8 @@ from datetime import datetime from typing import List, Optional from pydantic import BaseModel, ConfigDict +from app.models.models import Robot + class ImageBase(BaseModel): imageUrl: str localPath: Optional[str] = None @@ -132,6 +134,11 @@ class EditTemperatureDto(BaseModel): status: Optional[str] = None temperature: Optional[str] = None +class GetRobotDto(BaseModel): + number: Optional[str] = None + status: Optional[str] = None + onlineStatus: Optional[str] = None + # 后台查看事件详情 class BackStageEventDetail(BaseModel): eventId:str = None