From 21662d394458d5d5f8dd1fd30f3609a6d66bfc1c Mon Sep 17 00:00:00 2001 From: Misaka Date: Wed, 29 Jul 2026 19:58:10 +0800 Subject: [PATCH] feat(shunxin): cross-month calendar navigation for date-specific download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 顺心 Ant Design 日期面板跨月导航:目标日期不在当前月视窗时,读面板头部 .ant-picker-year-btn/.ant-picker-month-btn 得当前年月,按差值点 .ant-picker-header-prev-btn/next-btn 翻到目标月再选格子。应到(车辆点到)与 实到(卸车扫描记录)两处设日期统一改走 _shunxin_pick_date。 同月(offset 当月)行为不变,仅在跨月时多走翻月;与中通 _zto_flip_to_target_month 思路对称,适配 Ant Design 面板。年*12+月 比较天然支持跨年。 Co-Authored-By: Claude --- inbound_verify/sites/shunxin.py | 74 +++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/inbound_verify/sites/shunxin.py b/inbound_verify/sites/shunxin.py index 89e6cab..7d45489 100644 --- a/inbound_verify/sites/shunxin.py +++ b/inbound_verify/sites/shunxin.py @@ -88,6 +88,64 @@ def _remove_if_exists(path): pass +def _shunxin_navigate_picker_to_target(page, date_str, max_flips=24): + """顺心 Ant Design 单月面板跨月导航(车辆点到 / 卸车扫描记录 共用同一组件)。 + + 读面板头部 .ant-picker-year-btn / .ant-picker-month-btn 得当前显示的年月,按与目标 + 年月的差值点 .ant-picker-header-prev-btn(上月)/ .ant-picker-header-next-btn(下月), + 翻到目标月视窗。返回 True 表示当前视窗已是目标月(目标格子随后可见可点)。 + 调用前提:开始/结束时间输入已点开,.ant-picker-dropdown:visible 已就绪。 + """ + try: + ty, tm = (int(x) for x in date_str.split("-")[:2]) + except Exception: + return True # 解析不出就不翻,交由后续 cell.click 自行成败 + drop = page.locator(".ant-picker-dropdown:visible") + for _ in range(max_flips): + try: + cur_y = int( + re.search( + r"\d+", drop.locator(".ant-picker-year-btn").first.inner_text() + ).group() + ) + cur_m = int( + re.search( + r"\d+", drop.locator(".ant-picker-month-btn").first.inner_text() + ).group() + ) + except Exception: + return False + cur = cur_y * 12 + (cur_m - 1) + tgt = ty * 12 + (tm - 1) + if cur == tgt: + return True + btn_sel = ( + ".ant-picker-header-prev-btn" + if tgt < cur + else ".ant-picker-header-next-btn" + ) + drop.locator(btn_sel).first.click() + page.wait_for_timeout(300) + return False + + +def _shunxin_pick_date(page, date_str): + """在已打开的顺心 Ant Design 日期浮层上选中指定日期格子(含跨月翻月)。 + + 目标格子不在当前月视窗(跨月)时,先调 _shunxin_navigate_picker_to_target 翻到目标月, + 再点格子;同月则直接点。与中通 _zto_flip_to_target_month 思路对称,适配 Ant Design 面板。 + """ + cell = page.locator(f".ant-picker-dropdown:visible td[title='{date_str}']").first + if not cell.is_visible(): + print(f" ℹ️ 目标日期 {date_str} 不在当前月视窗,正在翻月导航 ...") + if not _shunxin_navigate_picker_to_target(page, date_str): + raise RuntimeError(f"翻月后仍无法定位目标日期格子 {date_str}") + cell = page.locator( + f".ant-picker-dropdown:visible td[title='{date_str}']" + ).first + cell.click() + + def shunxin_belonging(page): """读取顺心当前账号的归属网点名(仅在首页可见,须在导航离开首页前调用)。 @@ -238,17 +296,13 @@ def shunxin_expected_download_impl(page, out_tag="", force=False, date=None): print(" >> 设置起始时间...") page.get_by_placeholder("开始时间").click() page.wait_for_timeout(500) - page.locator( - f".ant-picker-dropdown:visible td[title='{start_date_str}']" - ).first.click() + _shunxin_pick_date(page, start_date_str) page.wait_for_timeout(300) print(" >> 设置截止时间...") page.get_by_placeholder("结束时间").click() page.wait_for_timeout(500) - page.locator( - f".ant-picker-dropdown:visible td[title='{today_str}']" - ).first.click() + _shunxin_pick_date(page, today_str) page.wait_for_timeout(300) # 确认日期 @@ -603,17 +657,13 @@ def shunxin_actual_download_impl(page, out_tag="", date=None): print(" >> 设置起始时间...") page.get_by_placeholder("开始时间").click() page.wait_for_timeout(500) - page.locator( - f".ant-picker-dropdown:visible td[title='{start_date_str}']" - ).first.click() + _shunxin_pick_date(page, start_date_str) page.wait_for_timeout(300) print(" >> 设置截止时间...") page.get_by_placeholder("结束时间").click() page.wait_for_timeout(500) - page.locator( - f".ant-picker-dropdown:visible td[title='{today_str}']" - ).first.click() + _shunxin_pick_date(page, today_str) page.wait_for_timeout(300) # 确认日期