feat: dedup expected data by handover_no before export submit
- store.get_existing_handover_nos: query PG expected_record.handover_no - inject dedup skip before submitting export in zto/yunda/anneng/shunxin - shunxin reads RTS handover_no from waybill-list view (method 1) - force-redownload switch threaded via task_spec -> dispatch -> impl - schema: add idx_expected_handover index Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -149,7 +149,7 @@ def shunxin_merge_final(kind, tags):
|
||||
pass
|
||||
|
||||
|
||||
def shunxin_expected_download(pages, foreground=True):
|
||||
def shunxin_expected_download(pages, foreground=True, force=False):
|
||||
"""顺心:应到货物数据下载(双账号/双归属地,内部含异常兜底重试与数据融合)。
|
||||
|
||||
pages 为该站点的 page 列表(双账号在同一窗口的各一个标签页)。
|
||||
@@ -175,7 +175,9 @@ def shunxin_expected_download(pages, foreground=True):
|
||||
ok = with_retry(
|
||||
f"顺心-{tag}",
|
||||
"应到",
|
||||
lambda p=pg, t=tag: shunxin_expected_download_impl(p, out_tag=t),
|
||||
lambda p=pg, t=tag, f=force: shunxin_expected_download_impl(
|
||||
p, out_tag=t, force=f
|
||||
),
|
||||
lambda p=pg: shunxin_reset(p),
|
||||
)
|
||||
if not ok:
|
||||
@@ -185,7 +187,7 @@ def shunxin_expected_download(pages, foreground=True):
|
||||
return True
|
||||
|
||||
|
||||
def shunxin_expected_download_impl(page, out_tag=""):
|
||||
def shunxin_expected_download_impl(page, out_tag="", force=False):
|
||||
"""顺心:应到货物数据下载(单次执行,无重试;供自动化测试探测原始结果用)。
|
||||
|
||||
out_tag 为归属地标签时,合并产物命名为「顺心-{out_tag}-应到货物数据.xlsx」,
|
||||
@@ -309,12 +311,44 @@ def shunxin_expected_download_impl(page, out_tag=""):
|
||||
count = waybill_btns.count()
|
||||
print(f">> 共发现 {count} 个班次需要导出。")
|
||||
|
||||
# 【去重】加载本站已落库交接单号;force=True 或查询失败时 existing=空集(不去重)。
|
||||
# 两账号共享同一集合(班次号/交接单号跨归属地不重叠)。
|
||||
if force:
|
||||
existing = set()
|
||||
print(">> [去重] 强制重下,跳过去重。")
|
||||
else:
|
||||
try:
|
||||
from inbound_verify import store
|
||||
|
||||
existing = store.get_existing_handover_nos("顺心")
|
||||
except Exception as _e:
|
||||
existing = set()
|
||||
print(f">> [去重] 加载已落库交接单号失败,本次不去重: {_e}")
|
||||
|
||||
for i in range(count):
|
||||
print(f" ⏳ 正在处理第 {i+1}/{count} 个班次...")
|
||||
|
||||
waybill_btns.nth(i).click()
|
||||
page.locator("label[title='运单查询']").wait_for(state="visible")
|
||||
|
||||
# 【方式1】运单列表界面已加载,读交接单号(RTS 开头)→ 已落库则退回列表跳过。
|
||||
# 交接单号格式 RTS\d{3}WJ\d+(如 RTS023WJ374837),用 [A-Z0-9]+ 连续匹配整段。
|
||||
# 读不到(DOM 变动/未渲染)则 handover_no 为空 → 不跳过(安全降级,继续导出)。
|
||||
handover_no = ""
|
||||
try:
|
||||
_txt = page.locator("text=/RTS\\d+/").first.inner_text(timeout=3000)
|
||||
_m = re.search(r"RTS[A-Z0-9]+", _txt)
|
||||
if _m:
|
||||
handover_no = _m.group(0)
|
||||
except Exception:
|
||||
pass
|
||||
print(f" -> 运单列表交接单号:{handover_no or '(未读到,不去重)'}")
|
||||
if handover_no and handover_no in existing:
|
||||
print(f" ⏭️ 交接单号 {handover_no} 已落库,跳过提交导出。")
|
||||
page.get_by_role("tab", name="车辆点到").click()
|
||||
page.wait_for_timeout(500)
|
||||
continue
|
||||
|
||||
# 4. 执行导出流程
|
||||
page.get_by_role("button", name="export 导出").click()
|
||||
|
||||
@@ -342,6 +376,11 @@ def shunxin_expected_download_impl(page, out_tag=""):
|
||||
_close_tab(page, "运单列表")
|
||||
_close_tab(page, "车辆点到")
|
||||
|
||||
# 【去重兜底】全部已落库/无数据 → 无导出任务,标签页已关,跳过下载轮询
|
||||
if not export_times:
|
||||
print(">> 本次无新班次需导出(全部已落库或无数据),结束。")
|
||||
return True
|
||||
|
||||
# 6. 前往数据导出页面去下载
|
||||
print(">> 正在前往【数据导出】界面...")
|
||||
page.locator("a[href='/dataExport']").click()
|
||||
@@ -477,7 +516,7 @@ def shunxin_expected_download_impl(page, out_tag=""):
|
||||
return False
|
||||
|
||||
|
||||
def shunxin_actual_download(pages, foreground=True):
|
||||
def shunxin_actual_download(pages, foreground=True, force=False):
|
||||
"""顺心:实到货物数据下载(双账号/双归属地,内部含异常兜底重试与数据融合)。
|
||||
|
||||
与 shunxin_expected_download 同构:读归属地 → 去重校验 → 顺序各账号下载 →
|
||||
|
||||
Reference in New Issue
Block a user