From 411072ef6b795e28bc51a0ee5621146dd8efc51b Mon Sep 17 00:00:00 2001 From: liyxie Date: Wed, 12 Nov 2025 21:26:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0account=5Fid=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E8=8E=B7=E5=8F=96=E6=B2=89=E9=99=8D=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/comprehensive_data.py | 80 ++++++++++++++++++++++---- app/schemas/comprehensive_data.py | 1 + app/services/checkpoint.py | 6 ++ app/services/section_data.py | 10 +++- app/services/settlement_data.py | 94 +++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+), 14 deletions(-) diff --git a/app/api/comprehensive_data.py b/app/api/comprehensive_data.py index 07580a5..36d5e59 100644 --- a/app/api/comprehensive_data.py +++ b/app/api/comprehensive_data.py @@ -232,20 +232,76 @@ def get_section(request: SectionDataQueryRequest, db: Session = Depends(get_db)) # 根据观测点id查询沉降数据 @router.post("/get_settlement", response_model=DataResponse) def get_settlement(request: SettlementDataQueryRequest, db: Session = Depends(get_db)): - """获取沉降数据,按上传时间倒序排序,支持分页参数(skip、limit)""" + """获取沉降数据,支持根据account_id查询(account_id -> 断面数据 -> 观测点数据 -> 沉降数据)""" try: logger.info(f"Querying settlement data with params: {request.dict()}") - result = settlement_service.search_settlement_data_formatted( - db, - id=request.id, - point_id=request.point_id, - nyid=request.NYID, - sjName=request.sjName, - workinfoname=request.workinfoname, - skip=request.skip, - limit=request.limit - ) - logger.info(f"Found {result['total']} settlement records, returning {len(result['data'])} records") + + # 如果提供了account_id,则按新逻辑查询 + if request.account_id: + logger.info(f"Using account_id to query: {request.account_id}") + + # 1. 根据account_id查询断面数据 + section_data_list = section_service.get_by_account_id(db, request.account_id) + logger.info(f"Found {len(section_data_list)} sections for account_id: {request.account_id}") + + if not section_data_list: + return DataResponse( + code=ResponseCode.SUCCESS, + message="未找到对应账号ID的断面数据", + total=0, + data=[] + ) + + # 2. 使用批量查询一次性获取所有观测点数据(避免循环查询) + section_ids = [section_data.section_id for section_data in section_data_list] + logger.info(f"Querying {len(section_ids)} sections for account_id: {request.account_id}") + + checkpoint_data_list = checkpoint_service.get_by_section_ids_batch(db, section_ids) + logger.info(f"Found {len(checkpoint_data_list)} checkpoints total") + + # 提取所有观测点ID(去重) + point_ids = [] + for checkpoint in checkpoint_data_list: + if checkpoint.point_id and checkpoint.point_id not in point_ids: + point_ids.append(checkpoint.point_id) + + logger.info(f"Total unique point_ids found: {len(point_ids)}") + + if not point_ids: + return DataResponse( + code=ResponseCode.SUCCESS, + message="未找到观测点数据", + total=0, + data=[] + ) + + # 3. 使用优化的批量查询方法(一次性查询,避免多次数据库访问) + result = settlement_service.search_settlement_data_by_point_ids_formatted( + db, + point_ids=point_ids, + id=request.id, + nyid=request.NYID, + sjName=request.sjName, + workinfoname=request.workinfoname, + skip=request.skip, + limit=request.limit + ) + logger.info(f"Found {result['total']} settlement records using optimized batch query, returning {len(result['data'])} records") + + else: + # 原逻辑:不提供account_id,按原有方式查询 + logger.info("Using original query logic without account_id") + result = settlement_service.search_settlement_data_formatted( + db, + id=request.id, + point_id=request.point_id, + nyid=request.NYID, + sjName=request.sjName, + workinfoname=request.workinfoname, + skip=request.skip, + limit=request.limit + ) + logger.info(f"Found {result['total']} settlement records using original logic, returning {len(result['data'])} records") return DataResponse( code=ResponseCode.SUCCESS, diff --git a/app/schemas/comprehensive_data.py b/app/schemas/comprehensive_data.py index 330ce9e..5e0c5b2 100644 --- a/app/schemas/comprehensive_data.py +++ b/app/schemas/comprehensive_data.py @@ -91,6 +91,7 @@ class SettlementDataQueryRequest(BaseModel): id: Optional[int] = None point_id: Optional[int] = None NYID: Optional[int] = None + account_id: Optional[str] = None # 账号ID,可选,不填则按原来逻辑查询 CVALUE: Optional[str] = None MAVALUE: Optional[str] = None MTIME_W: Optional[str] = None diff --git a/app/services/checkpoint.py b/app/services/checkpoint.py index d9542b1..6828bf7 100644 --- a/app/services/checkpoint.py +++ b/app/services/checkpoint.py @@ -124,3 +124,9 @@ class CheckpointService(BaseService[Checkpoint]): def get_by_section_id(self, db: Session, section_id: str) -> List[Checkpoint]: """根据section_id获取所有相关的测点信息""" return self.get_by_field(db, "section_id", section_id) + + def get_by_section_ids_batch(self, db: Session, section_ids: List[str]) -> List[Checkpoint]: + """批量根据section_id列表获取所有观测点数据(使用IN查询优化性能)""" + if not section_ids: + return [] + return db.query(Checkpoint).filter(Checkpoint.section_id.in_(section_ids)).all() diff --git a/app/services/section_data.py b/app/services/section_data.py index ac3a0ea..cb78c33 100644 --- a/app/services/section_data.py +++ b/app/services/section_data.py @@ -20,10 +20,16 @@ class SectionDataService(BaseService[SectionData]): """根据断面ID获取断面数据""" sections = self.get_by_field(db, "section_id", section_id) return sections[0] if sections else None - def get_by_account_id(self, db: Session, account_id: str) -> Optional[SectionData]: + def get_by_account_id(self, db: Session, account_id: str) -> List[SectionData]: """根据账号ID获取断面数据""" accounts = self.get_by_field(db, "account_id", account_id) - return accounts if accounts else None + return accounts if accounts else [] + + def get_by_account_id_batch(self, db: Session, account_ids: List[str]) -> List[SectionData]: + """批量根据账号ID列表获取断面数据(使用IN查询优化性能)""" + if not account_ids: + return [] + return db.query(SectionData).filter(SectionData.account_id.in_(account_ids)).all() def get_by_number(self, db: Session, number: str) -> List[SectionData]: """根据桥梁墩(台)编号获取断面数据""" return self.get_by_field(db, "number", number) diff --git a/app/services/settlement_data.py b/app/services/settlement_data.py index 74f00df..3aa99f4 100644 --- a/app/services/settlement_data.py +++ b/app/services/settlement_data.py @@ -70,6 +70,100 @@ class SettlementDataService(BaseService[SettlementData]): return query.all() + def search_settlement_data_by_point_ids_formatted(self, db: Session, + point_ids: List[str], + id: Optional[int] = None, + nyid: Optional[str] = None, + sjName: Optional[str] = None, + workinfoname: Optional[str] = None, + skip: int = 0, + limit: Optional[int] = None) -> Dict[str, Any]: + """ + 支持多个point_id的沉降数据批量查询(优化版本) + 一次性查询,避免多次数据库访问 + """ + if not point_ids: + return { + "data": [], + "total": 0, + "skip": skip, + "limit": limit + } + + # 先获取总数(不计分页) + count_query = db.query(SettlementData) + if id is not None: + count_query = count_query.filter(SettlementData.id == id) + if nyid is not None: + count_query = count_query.filter(SettlementData.NYID == nyid) + if sjName is not None: + count_query = count_query.filter(SettlementData.sjName == sjName) + if workinfoname is not None: + count_query = count_query.filter(SettlementData.workinfoname == workinfoname) + + # 支持多个point_id(使用IN查询) + count_query = count_query.filter(SettlementData.point_id.in_(point_ids)) + total_count = count_query.count() + + # 获取分页数据(使用相同的过滤条件) + query = db.query(SettlementData) + if id is not None: + query = query.filter(SettlementData.id == id) + if nyid is not None: + query = query.filter(SettlementData.NYID == nyid) + if sjName is not None: + query = query.filter(SettlementData.sjName == sjName) + if workinfoname is not None: + query = query.filter(SettlementData.workinfoname == workinfoname) + + # 支持多个point_id + query = query.filter(SettlementData.point_id.in_(point_ids)) + + # 按上传时间倒序排序 + query = query.order_by(SettlementData.createdate.desc()) + + # 添加分页支持 + if skip > 0: + query = query.offset(skip) + if limit is not None and limit > 0: + query = query.limit(limit) + + settlement_data = query.all() + + # 格式化结果 + result = [] + for settlement in settlement_data: + settlement_dict = { + "id": settlement.id, + "point_id": settlement.point_id, + "CVALUE": settlement.CVALUE, + "MAVALUE": settlement.MAVALUE, + "MTIME_W": settlement.MTIME_W, + "NYID": settlement.NYID, + "PRELOADH": settlement.PRELOADH, + "PSTATE": settlement.PSTATE, + "REMARK": settlement.REMARK, + "WORKINFO": settlement.WORKINFO, + "createdate": settlement.createdate, + "day": settlement.day, + "day_jg": settlement.day_jg, + "isgzjdxz": settlement.isgzjdxz, + "mavalue_bc": settlement.mavalue_bc, + "mavalue_lj": settlement.mavalue_lj, + "sjName": settlement.sjName, + "useflag": settlement.useflag, + "workinfoname": settlement.workinfoname, + "upd_remark": settlement.upd_remark + } + result.append(settlement_dict) + + return { + "data": result, + "total": total_count, + "skip": skip, + "limit": limit + } + def search_settlement_data_formatted(self, db: Session, id: Optional[int] = None, point_id: Optional[str] = None,