This commit is contained in:
Marsway 2026-03-04 13:56:58 +08:00
parent 473343f548
commit 7262a33a93
1 changed files with 79 additions and 15 deletions

View File

@ -79,6 +79,64 @@ def _normalize_job_no(v: Any) -> str:
return s.upper()
def _extract_oa_row_id_and_fields(row: dict[str, Any]) -> tuple[int | None, dict[str, Any]]:
"""
兼容不同 OA export 返回结构提取
- row_id
- 字段字典key=fieldCode, value=单元格对象或值
"""
field_map: dict[str, Any] = {}
row_id: int | None = None
# 结构 AmasterData 直接是 {field0001: {value,showValue}, ...}
master = row.get("masterData")
if isinstance(master, dict):
for k, v in master.items():
if isinstance(k, str) and k.startswith("field"):
field_map[k] = v
for candidate in (row.get("id"), row.get("masterDataId"), master.get("id")):
if candidate is None:
continue
try:
row_id = int(str(candidate))
break
except Exception:
continue
# 结构 BmasterTable.record.fields = [{name,value,showValue}, ...]
master_table = row.get("masterTable")
if isinstance(master_table, dict):
record = master_table.get("record")
if isinstance(record, dict):
fields = record.get("fields")
if isinstance(fields, list):
for fld in fields:
if not isinstance(fld, dict):
continue
name = str(fld.get("name") or "").strip()
if name:
field_map[name] = fld
if row_id is None:
rid = record.get("id")
if rid is not None:
try:
row_id = int(str(rid))
except Exception:
pass
# 结构 C行级 fields 列表
row_fields = row.get("fields")
if isinstance(row_fields, list):
for fld in row_fields:
if not isinstance(fld, dict):
continue
name = str(fld.get("name") or "").strip()
if name:
field_map[name] = fld
return row_id, field_map
def _choose_better_record(current: dict[str, Any], candidate: dict[str, Any]) -> dict[str, Any]:
def _score(item: dict[str, Any]) -> str:
record = item.get("recordInfo") or {}
@ -292,35 +350,41 @@ class SyncEhrToOaFormJob(BaseJob):
job_field_code = display_to_code["工号"]
oa_id_by_job_no: dict[str, int] = {}
oa_id_by_job_no_norm: dict[str, int] = {}
row_parse_miss = 0
for row in rows:
if not isinstance(row, dict):
continue
master = row.get("masterData") or {}
if not isinstance(master, dict):
continue
job_no = _cell_value(master.get(job_field_code))
row_id, field_map = _extract_oa_row_id_and_fields(row)
job_no = _cell_value(field_map.get(job_field_code))
if not job_no:
row_parse_miss += 1
if verbose_trace and row_parse_miss <= 20:
logger.info(
"OA 行解析未取到工号job_field=%s row_keys=%s field_keys_sample=%s",
job_field_code,
list(row.keys())[:20],
list(field_map.keys())[:20],
)
continue
row_id_raw = row.get("id")
if row_id_raw is None:
row_id_raw = row.get("masterDataId")
if row_id_raw is None:
row_id_raw = master.get("id")
if row_id_raw is None:
continue
try:
row_id = int(str(row_id_raw))
except Exception:
if row_id is None:
row_parse_miss += 1
if verbose_trace and row_parse_miss <= 20:
logger.info(
"OA 行解析未取到记录IDjob_no=%s row_keys=%s",
job_no,
list(row.keys())[:20],
)
continue
oa_id_by_job_no[job_no] = row_id
job_no_norm = _normalize_job_no(job_no)
if job_no_norm:
oa_id_by_job_no_norm[job_no_norm] = row_id
logger.info(
"OA 工号索引完成indexed_job_numbers=%s indexed_job_numbers_norm=%s",
"OA 工号索引完成indexed_job_numbers=%s indexed_job_numbers_norm=%s parse_miss=%s",
len(oa_id_by_job_no),
len(oa_id_by_job_no_norm),
row_parse_miss,
)
if verbose_trace:
for job_no, row_id in list(oa_id_by_job_no.items()):