update
This commit is contained in:
parent
51a488a5cb
commit
2992a2631c
|
|
@ -38,12 +38,17 @@ def _to_int_safe(v: Any) -> int:
|
||||||
|
|
||||||
def _scalar_value(raw: Any) -> str:
|
def _scalar_value(raw: Any) -> str:
|
||||||
if isinstance(raw, dict):
|
if isinstance(raw, dict):
|
||||||
val = raw.get("value")
|
val = None
|
||||||
if val is None or str(val).strip() == "":
|
for value_key in ("value", "showValue", "text", "Text", "displayValue", "DisplayValue"):
|
||||||
val = raw.get("showValue")
|
val = raw.get(value_key)
|
||||||
|
if val is not None and str(val).strip() != "":
|
||||||
|
break
|
||||||
|
if isinstance(val, (dict, list, tuple, set)):
|
||||||
|
return _scalar_value(val)
|
||||||
return str(val or "").strip()
|
return str(val or "").strip()
|
||||||
if isinstance(raw, (list, tuple, set)):
|
if isinstance(raw, (list, tuple, set)):
|
||||||
return "\n".join([str(x).strip() for x in raw if x is not None and str(x).strip() != ""])
|
values = [_scalar_value(x) for x in raw]
|
||||||
|
return "\n".join([x for x in values if x])
|
||||||
return str(raw or "").strip()
|
return str(raw or "").strip()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,6 +75,76 @@ def _translate_value(node: dict[str, Any], key: str | None) -> str:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _candidate_keys(key: str | None) -> list[str]:
|
||||||
|
if not key:
|
||||||
|
return []
|
||||||
|
candidates = [key, f"{key}Text"]
|
||||||
|
if key.endswith("Text"):
|
||||||
|
candidates.insert(0, key)
|
||||||
|
candidates.append(key[:-4])
|
||||||
|
out: list[str] = []
|
||||||
|
seen: set[str] = set()
|
||||||
|
for candidate in candidates:
|
||||||
|
s = str(candidate or "").strip()
|
||||||
|
if s and s not in seen:
|
||||||
|
seen.add(s)
|
||||||
|
out.append(s)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _deep_field_value(node: Any, key: str | None) -> str:
|
||||||
|
candidates = set(_candidate_keys(key))
|
||||||
|
if not candidates:
|
||||||
|
return ""
|
||||||
|
if isinstance(node, dict):
|
||||||
|
for candidate in candidates:
|
||||||
|
if candidate in node:
|
||||||
|
s = _scalar_value(node.get(candidate))
|
||||||
|
if s:
|
||||||
|
return s
|
||||||
|
for value in node.values():
|
||||||
|
s = _deep_field_value(value, key)
|
||||||
|
if s:
|
||||||
|
return s
|
||||||
|
elif isinstance(node, list):
|
||||||
|
for value in node:
|
||||||
|
s = _deep_field_value(value, key)
|
||||||
|
if s:
|
||||||
|
return s
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _collect_matching_keys(node: Any, keyword: str, *, limit: int = 30) -> list[str]:
|
||||||
|
matches: list[str] = []
|
||||||
|
seen: set[str] = set()
|
||||||
|
needle = str(keyword or "").lower()
|
||||||
|
if not needle:
|
||||||
|
return matches
|
||||||
|
|
||||||
|
def walk(current: Any) -> None:
|
||||||
|
if len(matches) >= limit:
|
||||||
|
return
|
||||||
|
if isinstance(current, dict):
|
||||||
|
for k, v in current.items():
|
||||||
|
key = str(k)
|
||||||
|
if needle in key.lower() and key not in seen:
|
||||||
|
seen.add(key)
|
||||||
|
matches.append(key)
|
||||||
|
if len(matches) >= limit:
|
||||||
|
return
|
||||||
|
walk(v)
|
||||||
|
if len(matches) >= limit:
|
||||||
|
return
|
||||||
|
elif isinstance(current, list):
|
||||||
|
for v in current:
|
||||||
|
walk(v)
|
||||||
|
if len(matches) >= limit:
|
||||||
|
return
|
||||||
|
|
||||||
|
walk(node)
|
||||||
|
return matches
|
||||||
|
|
||||||
|
|
||||||
def _field_value(item: dict[str, Any], key: str) -> str:
|
def _field_value(item: dict[str, Any], key: str) -> str:
|
||||||
emp = item.get("employeeInfo") or {}
|
emp = item.get("employeeInfo") or {}
|
||||||
rec = item.get("recordInfo") or {}
|
rec = item.get("recordInfo") or {}
|
||||||
|
|
@ -85,18 +160,9 @@ def _field_value(item: dict[str, Any], key: str) -> str:
|
||||||
s = _custom_prop_value(node.get("customProperties"), key)
|
s = _custom_prop_value(node.get("customProperties"), key)
|
||||||
if s:
|
if s:
|
||||||
return s
|
return s
|
||||||
for child in node.values():
|
s = _deep_field_value(node, key)
|
||||||
if not isinstance(child, dict):
|
if s:
|
||||||
continue
|
return s
|
||||||
s = _scalar_value(child.get(key))
|
|
||||||
if s:
|
|
||||||
return s
|
|
||||||
s = _translate_value(child, key)
|
|
||||||
if s:
|
|
||||||
return s
|
|
||||||
s = _custom_prop_value(child.get("customProperties"), key)
|
|
||||||
if s:
|
|
||||||
return s
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -555,11 +621,13 @@ class SyncEhrToAdUserJob(BaseJob):
|
||||||
workplace_text = _field_translate_or_value(item, work_location_text_key)
|
workplace_text = _field_translate_or_value(item, work_location_text_key)
|
||||||
street_address = _field_value(item, street_address_key)
|
street_address = _field_value(item, street_address_key)
|
||||||
if verbose_trace:
|
if verbose_trace:
|
||||||
|
address_candidate_keys = _collect_matching_keys(item, "extgzddxx") if not street_address else []
|
||||||
logger.info(
|
logger.info(
|
||||||
"AD 地址字段解析:sam=%s street_address_key=%s streetAddress=%r",
|
"AD 地址字段解析:sam=%s street_address_key=%s streetAddress=%r candidate_keys=%s",
|
||||||
sam,
|
sam,
|
||||||
street_address_key,
|
street_address_key,
|
||||||
street_address,
|
street_address,
|
||||||
|
address_candidate_keys,
|
||||||
)
|
)
|
||||||
company = default_company or _root_org_name(org, org_by_oid)
|
company = default_company or _root_org_name(org, org_by_oid)
|
||||||
location_attrs = _location_from_workplace(workplace_text or office, location_mappings)
|
location_attrs = _location_from_workplace(workplace_text or office, location_mappings)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue