feat(yunda): cross-month calendar navigation for date-specific download
韵达两个流程的日期组件不同,分别适配跨月翻月: - 应到(.layui-laydate 新版):读 .laydate-set-ym 当前年月,点 .laydate-prev-m/.laydate-next-m 翻月,格子 td[lay-ymd='YYYY-M-D']。 - 实到(#laydate_box 旧版):读 #laydate_y/#laydate_m 输入框值,点 #laydate_MM 内 .laydate_chprev/.laydate_chnext 翻月,格子 td[y][m][d]。 两处设日期改走 _yunda_pick_laydate_new / _yunda_pick_laydate_old,同月(offset 当月) 行为不变,仅跨月时翻月。年*12+月 比较天然支持跨年。 实到 #startDate/#endDate 保持普通 click(force=True 会在导航后 laydate 绑定完成前 抢先点击导致面板打不开);新增 #laydate_box:visible 就绪等待。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,64 @@ def _remove_if_exists(path):
|
||||
pass
|
||||
|
||||
|
||||
def _yunda_pick_laydate_new(ws_frame, page, date_ymd):
|
||||
"""应到(新版 laydate .layui-laydate):在已打开的面板上选中指定日期(含跨月翻月)。
|
||||
|
||||
目标格子 td[lay-ymd='YYYY-M-D'](非补零)不在当前月视窗时,读 .laydate-set-ym 的
|
||||
当前年月(形如「2026年7月」),按差值点 .laydate-prev-m / .laydate-next-m 翻到目标月,
|
||||
再点格子;同月则直接点。调用前提:#startTime/#endTime 已点开,.layui-laydate:visible 就绪。
|
||||
"""
|
||||
cal = ws_frame.locator(".layui-laydate:visible").first
|
||||
cell = cal.locator(f"td[lay-ymd='{date_ymd}']").first
|
||||
if not cell.is_visible():
|
||||
ty, tm = (int(x) for x in date_ymd.split("-")[:2])
|
||||
print(f" ℹ️ 目标日期 {date_ymd} 不在当前月视窗,正在翻月导航 ...")
|
||||
for _ in range(24):
|
||||
nums = re.findall(r"\d+", cal.locator(".laydate-set-ym").first.inner_text())
|
||||
if len(nums) >= 2:
|
||||
cur_y, cur_m = int(nums[0]), int(nums[1])
|
||||
if cur_y == ty and cur_m == tm:
|
||||
break
|
||||
cur = cur_y * 12 + (cur_m - 1)
|
||||
btn = (
|
||||
".laydate-prev-m"
|
||||
if (ty * 12 + (tm - 1)) < cur
|
||||
else ".laydate-next-m"
|
||||
)
|
||||
cal.locator(btn).first.click()
|
||||
page.wait_for_timeout(300)
|
||||
cell = cal.locator(f"td[lay-ymd='{date_ymd}']").first
|
||||
cell.click()
|
||||
|
||||
|
||||
def _yunda_pick_laydate_old(ws_frame, page, date_ymd):
|
||||
"""实到(旧版 laydate #laydate_box):在已打开的面板上选中指定日期(含跨月翻月)。
|
||||
|
||||
目标格子 td[y][m][d](非补零)不在当前月视窗时,读 #laydate_y/#laydate_m 输入框值
|
||||
(形如「2026年」「07月」)得当前年月,按差值点 #laydate_MM 内 .laydate_chprev /
|
||||
.laydate_chnext 翻到目标月,再点格子;同月则直接点。调用前提:#startDate/#endDate
|
||||
已点开(force=True),#laydate_box:visible 就绪。
|
||||
"""
|
||||
box = ws_frame.locator("#laydate_box:visible").first
|
||||
ty, tm, td = (int(x) for x in date_ymd.split("-")[:3])
|
||||
cell = box.locator(f"td[y='{ty}'][m='{tm}'][d='{td}']").first
|
||||
if not cell.is_visible():
|
||||
print(f" ℹ️ 目标日期 {date_ymd} 不在当前月视窗,正在翻月导航 ...")
|
||||
for _ in range(24):
|
||||
yv = box.locator("#laydate_y").first.evaluate("e=>e.value")
|
||||
mv = box.locator("#laydate_m").first.evaluate("e=>e.value")
|
||||
cur_y = int(re.search(r"\d+", yv).group())
|
||||
cur_m = int(re.search(r"\d+", mv).group())
|
||||
if cur_y == ty and cur_m == tm:
|
||||
break
|
||||
cur = cur_y * 12 + (cur_m - 1)
|
||||
btn = ".laydate_chprev" if (ty * 12 + (tm - 1)) < cur else ".laydate_chnext"
|
||||
box.locator(f"#laydate_MM {btn}").first.click()
|
||||
page.wait_for_timeout(300)
|
||||
cell = box.locator(f"td[y='{ty}'][m='{tm}'][d='{td}']").first
|
||||
cell.click()
|
||||
|
||||
|
||||
def _resolve_export_frame(ws_frame):
|
||||
"""定位韵达数据导出面板内嵌的 iframe。
|
||||
|
||||
@@ -228,7 +286,7 @@ def yunda_expected_download_impl(page, force=False, date=None):
|
||||
|
||||
calendar1 = ws_frame.locator(".layui-laydate:visible").first
|
||||
calendar1.wait_for(state="visible", timeout=5000)
|
||||
calendar1.locator(f"td[lay-ymd='{start_date_ymd}']").click()
|
||||
_yunda_pick_laydate_new(ws_frame, page, start_date_ymd)
|
||||
calendar1.locator(".laydate-btns-confirm").click()
|
||||
page.wait_for_timeout(400)
|
||||
|
||||
@@ -238,7 +296,7 @@ def yunda_expected_download_impl(page, force=False, date=None):
|
||||
|
||||
calendar2 = ws_frame.locator(".layui-laydate:visible").first
|
||||
calendar2.wait_for(state="visible", timeout=5000)
|
||||
calendar2.locator(f"td[lay-ymd='{today_ymd}']").click()
|
||||
_yunda_pick_laydate_new(ws_frame, page, today_ymd)
|
||||
calendar2.locator(".laydate-btns-confirm").click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
@@ -472,8 +530,8 @@ def yunda_actual_download_impl(page, date=None):
|
||||
target = datetime.strptime(date, "%Y-%m-%d")
|
||||
else:
|
||||
target = today - timedelta(days=offset)
|
||||
start_date = target # 单日范围:起止同日
|
||||
today = target # 让下方"截止时间"选择器也指向 target
|
||||
# 旧版 laydate 的日期格子 td[y][m][d] 用非补零整数值;单日范围起止同日
|
||||
target_ymd = f"{target.year}-{target.month}-{target.day}"
|
||||
src = f"指定 {date}" if date else f"偏移 {offset},0=今天"
|
||||
print(
|
||||
f">> 设置实到查询日期: [{target.year}-{target.month}-{target.day}]({src})"
|
||||
@@ -482,19 +540,19 @@ def yunda_actual_download_impl(page, date=None):
|
||||
print(" >> 正在设定起始时间...")
|
||||
ws_frame.locator("#startDate").click()
|
||||
page.wait_for_timeout(400)
|
||||
box1 = ws_frame.locator("#laydate_box:visible").first
|
||||
box1.locator(
|
||||
f"td[y='{start_date.year}'][m='{start_date.month}'][d='{start_date.day}']"
|
||||
).click()
|
||||
ws_frame.locator("#laydate_box:visible").first.wait_for(
|
||||
state="visible", timeout=5000
|
||||
)
|
||||
_yunda_pick_laydate_old(ws_frame, page, target_ymd)
|
||||
page.wait_for_timeout(400)
|
||||
|
||||
print(" >> 正在设定截止时间...")
|
||||
ws_frame.locator("#endDate").click()
|
||||
page.wait_for_timeout(400)
|
||||
box2 = ws_frame.locator("#laydate_box:visible").first
|
||||
box2.locator(
|
||||
f"td[y='{today.year}'][m='{today.month}'][d='{today.day}']"
|
||||
).click()
|
||||
ws_frame.locator("#laydate_box:visible").first.wait_for(
|
||||
state="visible", timeout=5000
|
||||
)
|
||||
_yunda_pick_laydate_old(ws_frame, page, target_ymd)
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
print(" >> 正在变更扫描类型为【到件】...")
|
||||
|
||||
Reference in New Issue
Block a user