导出数据格式处理

This commit is contained in:
lhx
2025-11-08 17:10:24 +08:00
parent 7633e22d99
commit 9f71f3a073
2 changed files with 118 additions and 49 deletions

View File

@@ -13,6 +13,7 @@ from ..services.account import AccountService
from ..core.exceptions import DataNotFoundException, AccountNotFoundException
import pandas as pd
import logging
from ..utils.time_utils import TimeUtils
from datetime import datetime
logger = logging.getLogger(__name__)
@@ -25,14 +26,6 @@ class ExportExcelService:
self.settlement_service = SettlementDataService()
self.level_service = LevelDataService()
def get_field_comments(self, model_class) -> Dict[str, str]:
"""获取模型字段的注释信息"""
comments = {}
for column in model_class.__table__.columns:
if column.comment:
comments[column.name] = column.comment
return comments
def merge_settlement_with_related_data(self,
db: Session,
settlement_data: SettlementData,
@@ -43,48 +36,62 @@ class ExportExcelService:
合并沉降数据与关联数据去除重复和id字段
"""
result = {}
# 导出数据列格式
desired_column_config = [
{"display_name": "观测点名称", "model_class": Checkpoint, "field_name_in_model": "aname"},
{"display_name": "断面里程", "model_class": SectionData, "field_name_in_model": "mileage"},
{"display_name": "工点名称", "model_class": SectionData, "field_name_in_model": "work_site"},
{"display_name": "水准线路编码", "model_class": LevelData, "field_name_in_model": "linecode"},
{"display_name": "修正量mm", "model_class": SettlementData, "field_name_in_model": "CVALUE"},
{"display_name": "成果值m", "model_class": SettlementData, "field_name_in_model": "MAVALUE"},
{"display_name": "埋设日期", "model_class": Checkpoint, "field_name_in_model": "burial_date"},
{"display_name": "观测时间", "model_class": SettlementData, "field_name_in_model": "MTIME_W"},
{"display_name": "观测阶段", "model_class": SettlementData, "field_name_in_model": "workinfoname"},
{"display_name": "累计天数", "model_class": SettlementData, "field_name_in_model": "day"},
{"display_name": "两次观测时间间隔", "model_class": SettlementData, "field_name_in_model": "day_jg"},
{"display_name": "本次沉降mm", "model_class": SettlementData, "field_name_in_model": "mavalue_bc"},
{"display_name": "累计沉降(mm)", "model_class": SettlementData, "field_name_in_model": "mavalue_lj"},
{"display_name": "上传时间", "model_class": SettlementData, "field_name_in_model": "createdate"},
{"display_name": "司镜人员", "model_class": SettlementData, "field_name_in_model": "sjName"},
{"display_name": "基础类型", "model_class": SectionData, "field_name_in_model": "basic_types"},
{"display_name": "桥墩台高度", "model_class": SectionData, "field_name_in_model": "height"},
{"display_name": "断面状态", "model_class": SectionData, "field_name_in_model": "status"},
{"display_name": "桥梁墩(台)编号", "model_class": SectionData, "field_name_in_model": "number"},
{"display_name": "过渡段", "model_class": SectionData, "field_name_in_model": "transition_paragraph"},
{"display_name": "设计填土高度", "model_class": SectionData, "field_name_in_model": "design_fill_height"},
{"display_name": "压实层厚度", "model_class": SectionData, "field_name_in_model": "compression_layer_thickness"},
{"display_name": "处理深度", "model_class": SectionData, "field_name_in_model": "treatment_depth"},
{"display_name": "地基处理方法", "model_class": SectionData, "field_name_in_model": "foundation_treatment_method"},
{"display_name": "围岩级别", "model_class": SectionData, "field_name_in_model": "rock_mass_classification"},
{"display_name": "工作基点名称序列", "model_class": LevelData, "field_name_in_model": "benchmarkids"},
{"display_name": "工作基点高程序列(m)", "model_class": LevelData, "field_name_in_model": "wsphigh"},
{"display_name": "水准_上传时间", "model_class": LevelData, "field_name_in_model": "createDate"},
{"display_name": "备注", "model_class": SettlementData, "field_name_in_model": "upd_remark"}
]
# 沉降数据字段映射(用注释名作为键)
settlement_comments = self.get_field_comments(SettlementData)
settlement_dict = settlement_data.to_dict()
for field_name, value in settlement_dict.items():
# 跳过id字段
if field_name == 'id':
continue
# 使用注释名作为键,如果没有注释则使用字段名
key = settlement_comments.get(field_name, field_name)
result[key] = value
result = {item["display_name"]: None for item in desired_column_config}
# 断面数据字段映射(添加前缀)
section_comments = self.get_field_comments(SectionData)
section_dict = section_data.to_dict()
for field_name, value in section_dict.items():
# 跳过id和account_id字段
if field_name in ['id', 'account_id']:
continue
key = section_comments.get(field_name, field_name)
result[f"断面_{key}"] = value
# 观测点数据字段映射(添加前缀)
checkpoint_comments = self.get_field_comments(Checkpoint)
checkpoint_dict = checkpoint_data.to_dict()
for field_name, value in checkpoint_dict.items():
# 跳过id和section_id字段section_id可能重复
if field_name in ['id', 'section_id']:
continue
key = checkpoint_comments.get(field_name, field_name)
result[f"观测点_{key}"] = value
# 水准数据字段映射(添加前缀)
data_map_by_class = {
SettlementData: settlement_data.to_dict(),
SectionData: section_data.to_dict(),
Checkpoint: checkpoint_data.to_dict(),
}
# 对于可选的 level_data只有当它存在时才添加到映射中
if level_data is not None:
level_comments = self.get_field_comments(LevelData)
level_dict = level_data.to_dict()
for field_name, value in level_dict.items():
# 跳过id和NYID字段NYID可能重复
if field_name in ['id', 'NYID']:
continue
key = level_comments.get(field_name, field_name)
result[f"水准_{key}"] = value
data_map_by_class[LevelData] = level_data.to_dict()
for config_item in desired_column_config:
display_name = config_item["display_name"]
model_class = config_item["model_class"]
field_name_in_model = config_item["field_name_in_model"]
# 检查这个模型类的数据是否存在于映射中
if model_class in data_map_by_class:
source_dict = data_map_by_class[model_class]
# 检查模型数据中是否包含这个字段
if field_name_in_model in source_dict:
# 将从源数据中取出的值赋给结果字典中对应的 display_name 键
result[display_name] = source_dict[field_name_in_model]
return result
@@ -136,7 +143,7 @@ class ExportExcelService:
if not all_settlements:
logger.warning("未找到任何沉降数据")
logger.info(f"观测点id集合{point_ids}")
# logger.info(f"观测点id集合{point_ids}")
raise DataNotFoundException("未找到任何沉降数据")
logger.info(f"批量查询到 {len(all_settlements)} 条沉降数据")
@@ -162,6 +169,7 @@ class ExportExcelService:
# 建立NYID->水准数据映射
nyid_level_map = {}
for level_data in all_level_data:
level_data.createDate = TimeUtils.datetime_to_date_string(level_data.createDate)
if level_data.NYID not in nyid_level_map:
nyid_level_map[level_data.NYID] = level_data
@@ -170,11 +178,33 @@ class ExportExcelService:
for section in sections:
checkpoints = section_checkpoint_map.get(section.section_id, [])
for checkpoint in checkpoints:
checkpoint.burial_date = TimeUtils.string_to_date_string(checkpoint.burial_date)
settlements = point_settlement_map.get(checkpoint.point_id, [])
for settlement in settlements:
settlement.MTIME_W = TimeUtils.datetime_to_date_string(settlement.MTIME_W)
settlement.createdate = TimeUtils.datetime_to_date_string(settlement.createdate)
import decimal
d = decimal.Decimal(settlement.CVALUE)
bc = decimal.Decimal(settlement.mavalue_bc)
lj = decimal.Decimal(settlement.mavalue_lj)
d = d * 1000
bc = bc * 1000
lj = lj * 1000
if d == d.to_integral_value():
settlement.CVALUE = str(int(d))
else:
settlement.CVALUE = str(d)
if bc == bc.to_integral_value():
settlement.mavalue_bc = str(int(bc))
else:
settlement.mavalue_bc = str(bc)
if lj == lj.to_integral_value():
settlement.mavalue_lj = str(int(lj))
else:
settlement.mavalue_lj = str(lj)
# 从映射中获取水准数据
level_data = nyid_level_map.get(settlement.NYID)
# 合并数据
merged_record = self.merge_settlement_with_related_data(
db, settlement, section, checkpoint, level_data