From ea2362a5f2fd62203be6a983800d46610cb45701 Mon Sep 17 00:00:00 2001 From: Marsway Date: Wed, 25 Mar 2026 10:30:58 +0800 Subject: [PATCH] fixing --- extensions/sync_ehr_to_oa/job.py | 85 +++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/extensions/sync_ehr_to_oa/job.py b/extensions/sync_ehr_to_oa/job.py index db5a1f3..570b255 100644 --- a/extensions/sync_ehr_to_oa/job.py +++ b/extensions/sync_ehr_to_oa/job.py @@ -610,6 +610,26 @@ class SyncEhrToOaFormJob(BaseJob): failed_count = 0 failed_data: dict[str, str] = {} do_trigger_bool = _to_bool_or_none(do_trigger) + + def _call_batch_update(*, form_code: str, chunk_rows: list[dict[str, Any]]) -> tuple[dict[str, Any], dict[str, Any], dict[str, Any]]: + resp_local = seeyon.batch_update_cap4_form_soap( + formCode=form_code, + loginName=oa_login_name, + rightId=oa_right_id, + dataList=chunk_rows, + uniqueFiled=[job_field_code], + doTrigger=do_trigger_bool, + ) + rj_local = resp_local.json() if resp_local.content else {} + code_local = int(rj_local.get("code", -1)) + if code_local != 0: + raise RuntimeError(f"OA batch-update failed code={code_local} message={rj_local.get('message')!r} formCode={form_code!r}") + data_local = rj_local.get("data") or {} + fd_local = data_local.get("failedData") or {} + if not isinstance(fd_local, dict): + fd_local = {} + return rj_local, data_local, fd_local + for i in range(0, len(data_list), batch_size): chunk = data_list[i : i + batch_size] if verbose_trace: @@ -625,53 +645,62 @@ class SyncEhrToOaFormJob(BaseJob): logger.info("批量更新字段:row_id=%s field=%s value=%s", row_id, fld.get("name"), fld.get("value")) except Exception: logger.info("批量更新行日志输出失败,已忽略") - resp = seeyon.batch_update_cap4_form_soap( - formCode=oa_form_code, - loginName=oa_login_name, - rightId=oa_right_id, - dataList=chunk, - uniqueFiled=[job_field_code], - doTrigger=do_trigger_bool, - ) - rj = resp.json() if resp.content else {} - code = int(rj.get("code", -1)) - if code != 0: - raise RuntimeError(f"OA batch-update failed code={code} message={rj.get('message')!r}") - - data = rj.get("data") or {} + used_form_code = oa_form_code + rj, data, fd = _call_batch_update(form_code=used_form_code, chunk_rows=chunk) message = str(rj.get("message") or "") - success_count += int(data.get("successCount", 0) or 0) - failed_count += int(data.get("failedCount", 0) or 0) - fd = data.get("failedData") or {} - if isinstance(fd, dict): - for k, v in fd.items(): - failed_data[str(k)] = str(v) - else: - fd = {} + + chunk_success = int(data.get("successCount", 0) or 0) + chunk_failed = int(data.get("failedCount", 0) or 0) + all_no_master = ( + chunk_success == 0 + and chunk_failed == len(chunk) + and len(fd) > 0 + and all("没有主表记录错误" in str(v or "") for v in fd.values()) + ) + # 兜底:若 formCode 选错,改用主表名重试一次。 + if all_no_master and used_form_code != oa_master_table_name: + logger.warning( + "OA batch-update 全量无主表记录,使用主表名 formCode 重试一次:origin_formCode=%s retry_formCode=%s chunk=%s", + used_form_code, + oa_master_table_name, + i // batch_size + 1, + ) + used_form_code = oa_master_table_name + rj, data, fd = _call_batch_update(form_code=used_form_code, chunk_rows=chunk) + message = str(rj.get("message") or "") + chunk_success = int(data.get("successCount", 0) or 0) + chunk_failed = int(data.get("failedCount", 0) or 0) + + success_count += chunk_success + failed_count += chunk_failed + for k, v in fd.items(): + failed_data[str(k)] = str(v) # 打印失败原因样本,避免只有计数没有原因。 if fd: sample_items = list(fd.items())[:20] logger.warning( - "OA batch-update failedData sample chunk=%s size=%s message=%s sample=%s", + "OA batch-update failedData sample chunk=%s size=%s formCode=%s message=%s sample=%s", i // batch_size + 1, len(chunk), + used_form_code, message, sample_items, ) logger.info( - "OA batch-update chunk done chunk_size=%s success=%s failed=%s message=%s", + "OA batch-update chunk done chunk_size=%s success=%s failed=%s formCode=%s message=%s", len(chunk), - int(data.get("successCount", 0) or 0), - int(data.get("failedCount", 0) or 0), + chunk_success, + chunk_failed, + used_form_code, message, ) # 若整批 100% 失败,立即抛错终止并返回样本,避免任务表面继续执行。 - if int(data.get("successCount", 0) or 0) == 0 and int(data.get("failedCount", 0) or 0) == len(chunk): + if chunk_success == 0 and chunk_failed == len(chunk): raise RuntimeError( "OA batch-update chunk all failed; " - f"message={message!r}; failed_sample={list(fd.items())[:20] if isinstance(fd, dict) else fd!r}" + f"formCode={used_form_code!r}; message={message!r}; failed_sample={list(fd.items())[:20] if isinstance(fd, dict) else fd!r}" ) return {