diff --git a/app/services/settlement_data.py b/app/services/settlement_data.py index 77960df..49ba10d 100644 --- a/app/services/settlement_data.py +++ b/app/services/settlement_data.py @@ -10,6 +10,7 @@ from ..models.level_data import LevelData from ..models.section_data import SectionData import logging from datetime import datetime +from sqlalchemy import distinct logger = logging.getLogger(__name__) class SettlementDataService(BaseService[SettlementData]): @@ -48,7 +49,11 @@ class SettlementDataService(BaseService[SettlementData]): skip: int = 0, limit: Optional[int] = None) -> List[SettlementData]: """根据多个条件搜索沉降数据,按上传时间倒序排序""" - query = db.query(SettlementData) + # query = db.query(SettlementData) + # 返回数据多加一个 aname 字段 + query = db.query(SettlementData, Checkpoint.aname).outerjoin( + Checkpoint, SettlementData.point_id == Checkpoint.point_id + ) if id is not None: query = query.filter(SettlementData.id == id) @@ -69,8 +74,15 @@ class SettlementDataService(BaseService[SettlementData]): query = query.offset(skip) if limit is not None and limit > 0: query = query.limit(limit) + result_tuples = query.all() + settlement_data_list = [] + for settlement, aname in result_tuples: + # 动态添加aname属性,无匹配时为None + setattr(settlement, 'aname', aname) + settlement_data_list.append(settlement) - return query.all() + return settlement_data_list + # return query.all() def search_settlement_data_by_point_ids_formatted(self, db: Session, point_ids: List[str], @@ -176,7 +188,9 @@ class SettlementDataService(BaseService[SettlementData]): limit: Optional[int] = None) -> Dict[str, Any]: """查询沉降数据并返回格式化结果,按上传时间倒序排序(支持分页)""" # 先获取总数(不计分页) - count_query = db.query(SettlementData) + count_query = db.query(distinct(SettlementData.id)).outerjoin( + Checkpoint, SettlementData.point_id == Checkpoint.point_id + ) if id is not None: count_query = count_query.filter(SettlementData.id == id) if point_id is not None: @@ -196,6 +210,7 @@ class SettlementDataService(BaseService[SettlementData]): for settlement in settlement_data: settlement_dict = { "id": settlement.id, + "aname": settlement.aname, "point_id": settlement.point_id, "CVALUE": settlement.CVALUE, "MAVALUE": settlement.MAVALUE, diff --git a/app/utils/construction_monitor.py b/app/utils/construction_monitor.py index a7a5592..b3290a5 100644 --- a/app/utils/construction_monitor.py +++ b/app/utils/construction_monitor.py @@ -2,8 +2,11 @@ from datetime import datetime from typing import List, Dict import warnings import copy +# 注意:根据实际项目路径调整导入,若本地测试可注释掉 from ..core.logging_config import get_logger + logger = get_logger(__name__) + class ConstructionMonitorUtils: def __init__(self): # 原始工况周期映射表(保持不变) @@ -33,7 +36,7 @@ class ConstructionMonitorUtils: "轨道铺设完成后,12个月以后": 180, "填筑或堆载,一般情况": 1, "填筑或堆载,沉降量突变情况": 1, - "填筑或堆载,两次填筑间隔时间较长情况": 3, + "填筑或堆载,两次填筑间隔时间较长情况": 3, # 该工况原周期为3天 "堆载预压或路基填筑完成,第1至3个月": 7, "堆载预压或路基填筑完成,第4至6个月": 14, "堆载预压或路基填筑完成,6个月以后": 30, @@ -44,8 +47,7 @@ class ConstructionMonitorUtils: "轨道板(道床)铺设后,第2至3个月": 30, "轨道板(道床)铺设后,3个月以后": 90, "架桥机(运梁车) 首次通过后": 7, - "架桥机(运梁车) 首次通过前":1, - + "架桥机(运梁车) 首次通过前": 1, } # 构建中英文括号+逗号兼容映射表 self.compatible_periods = self._build_compatible_brackets_map() @@ -103,6 +105,8 @@ class ConstructionMonitorUtils: continue base_condition = None + # 新增:标记是否为冬休回溯到合法工况的场景 + is_winter_break = False # 初始化冬休标识 if latest_condition != "冬休": if latest_condition not in self.compatible_periods: result["error_data"].append(latest_item) @@ -124,6 +128,7 @@ class ConstructionMonitorUtils: base_condition = None break base_condition = history_condition + is_winter_break = True # 触发:冬休且回溯到合法历史工况 break item_copy = copy.deepcopy(latest_item) @@ -147,16 +152,29 @@ class ConstructionMonitorUtils: result["winter"].append(item_copy) continue - period = self.compatible_periods[base_condition] + # 核心修改:冬休回溯场景下调整测量间隔(基准周期) + original_period = self.compatible_periods[base_condition] + if is_winter_break: + # 规则1:原周期为3天则改为7天;规则2:其他周期直接翻倍 + if original_period == 3: + adjusted_period = 7 + else: + adjusted_period = original_period * 2 + else: + # 非冬休场景,使用原始周期 + adjusted_period = original_period + + # 基于调整后的周期计算剩余天数 days_passed = (calc_date - create_date).days - due_days = period - days_passed + due_days = adjusted_period - days_passed if due_days < 0: item_copy["remaining"] = 0 - int(abs(due_days)) result["error_data"].append(item_copy) warn_msg = ( f"【超期警报】测点{point_idx} 最新工况'{latest_condition}'({create_date})" - f"已超期{abs(due_days)}天!基准工况:{base_condition},周期{period}天" + f"已超期{abs(due_days)}天!基准工况:{base_condition}," + f"原始周期{original_period}天{',冬休调整后周期'+str(adjusted_period)+'天' if is_winter_break else ''}" ) logger.warning(warn_msg) warnings.warn(warn_msg, UserWarning) diff --git a/app/utils/scheduler.py b/app/utils/scheduler.py index fffcaba..eb8ba2b 100644 --- a/app/utils/scheduler.py +++ b/app/utils/scheduler.py @@ -241,6 +241,7 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0): # 2. 计算到期数据 monitor = ConstructionMonitorUtils() daily_data = monitor.get_due_data(result,start=start,end=end) + # time.sleep(10000) data = daily_data['data'] error_data = daily_data['error_data'] @@ -249,10 +250,13 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0): # 3. 循环处理冬休数据,追溯历史非冬休记录 max_num = 1 - while winters: + print(f"首次获取冬休数据完成,共{len(winters)}条记录") + while 1: max_num += 1 + print(max_num) # 提取冬休数据的point_id列表 - new_list = [w['point_id'] for w in winters] + new_list = [int(w['point_id']) for w in winters] + print(new_list) # 获取更多历史记录 nyid_list = daily_service.get_nyid_by_point_id(db, new_list, max_num) w_list = monitor.get_due_data(nyid_list,start=start,end=end) @@ -262,14 +266,14 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0): # 过期数据一并处理 # data.extend(w_list['error_data']) error_data.extend(w_list['error_data']) - print(w_list) + if winters == []: + break data.extend(error_data) # 4. 初始化服务实例 level_service = LevelDataService() checkpoint_db = CheckpointService() section_db = SectionDataService() account_service = AccountService() - print(len(data)) # 5. 关联其他表数据(核心逻辑保留) for d in data: # 处理 LevelData(假设返回列表,取第一条) @@ -294,7 +298,7 @@ def scheduled_get_max_nyid_by_point_id(start: int = 0,end: int = 0): d['account_data'] = account_response.__dict__ if account_response else None else: d['account_data'] = None - + print(f"一共有{len(data)}条数据{data}") # 6. 构造DailyData数据并批量创建 # daily_create_data1 = set() daily_create_data = []