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:
Misaka_Company
2026-07-29 10:57:07 +08:00
parent d74a35844f
commit f710622a3d
11 changed files with 663 additions and 28 deletions

View File

@@ -454,14 +454,14 @@ def _web_handler(site, download_func):
焦点;交互模式置顶便于调试。顺心是 page 列表,置顶标志透传给 shunxin_download。
"""
def handler(ctx):
def handler(ctx, force=False):
pg = ctx.pages_map[site]
if isinstance(pg, list):
# 顺心双账号:置顶与否交给 shunxin_download 在逐账号循环里按 foreground 决定
return download_func(pg, foreground=ctx.foreground)
return download_func(pg, foreground=ctx.foreground, force=force)
if ctx.foreground:
pg.bring_to_front()
return download_func(pg)
return download_func(pg, force=force)
return handler
@@ -470,11 +470,13 @@ def _site_undelivered_handler(site):
"""4 站未到:下应到+实到 → 比对写 downloads/<站>-未到数据.xlsx。
任一下载失败 → 清掉旧未到文件、返回 False前端不展示陈旧未到"""
def handler(ctx):
def handler(ctx, force=False):
# 各站下载入口约定返回 True/False顺心历史返回 None视为成功与 dispatch 一致)
exp_ok = TASK_HANDLERS[(site, "expected")](ctx) is not False
exp_ok = TASK_HANDLERS[(site, "expected")](ctx, force) is not False
act_ok = (
(TASK_HANDLERS[(site, "actual")](ctx) is not False) if exp_ok else False
(TASK_HANDLERS[(site, "actual")](ctx, force) is not False)
if exp_ok
else False
)
if exp_ok and act_ok:
return compare.write_site_file(site)
@@ -502,10 +504,14 @@ TASK_HANDLERS = {
("韵达", "expected"): _web_handler("韵达", yunda.yunda_expected_download),
("韵达", "actual"): _web_handler("韵达", yunda.yunda_actual_download),
("韵达", "undelivered"): _site_undelivered_handler("韵达"),
("安能", "expected"): lambda ctx: anneng.anneng_expected_download(),
("安能", "actual"): lambda ctx: anneng.anneng_actual_download(),
("安能", "expected"): lambda ctx, force=False: anneng.anneng_expected_download(
force=force
),
("安能", "actual"): lambda ctx, force=False: anneng.anneng_actual_download(
force=force
),
("安能", "undelivered"): _site_undelivered_handler("安能"),
("__compare__", "compare"): lambda ctx: (compare.main() or True),
("__compare__", "compare"): lambda ctx, force=False: (compare.main() or True),
}
@@ -594,7 +600,7 @@ def dispatch_task(ctx, task_spec):
if handler is None:
return (state_store.TASK_FAILED, f"未知任务: {site}/{kind}")
try:
ret = handler(ctx)
ret = handler(ctx, bool(task_spec.get("force", False)))
if ret is False:
return (state_store.TASK_FAILED, "任务执行失败(重试耗尽)")
_record_business_date(site, kind)