按站点指定下载日期偏移(0=今天…30)+ 修复启动陈旧登录态

偏移量功能(前端/API 可配,服务端持久化、多用户共享):
- state_store:新增 site_config 表 + get_offset / set_offset(0..30 钳制) / get_all_offsets
- server:新增 GET/PUT /config(百世锁定当天,不可配置)
- 顺心/中通/韵达/安能(各 expected+actual):日期逻辑由 query_days 范围改为读 offset
  算单日 target=今天-offset,起止同日;百世仍走当日
- config.example.yaml:query_days 标记为已废弃

修复启动时显示上一会话陈旧登录态:
- state_store:新增 reset_login_states(登录态会话级,启动重置为 unknown;数据态会话无关、保留)
- runtime.launch_and_prepare:启动时对各站重置登录态,心跳就绪后重新探测写真实值

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-07-17 21:27:52 +08:00
parent 66bd8af421
commit 26a94999dc
8 changed files with 151 additions and 106 deletions

View File

@@ -8,6 +8,7 @@ from datetime import datetime
import pandas as pd
from paths import DOWNLOAD_DIR, CONFIG_PATH
import state_store
def with_retry(site_name, label, flow, reset, max_attempts=3):
@@ -141,17 +142,10 @@ def zto_expected_download_impl(page):
print(">> 正在检测表格统计面板 (#inEwbCount)...")
ewb_frame.locator("#inEwbCount").wait_for(state="attached", timeout=15000)
# 读取 YAML 配置设定天数
query_days = 1
try:
if os.path.exists(CONFIG_PATH):
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
config = yaml.safe_load(f) or {}
query_days = int(config.get("zto", {}).get("query_days", 1))
except Exception as e:
print(f" ⚠️ 读取 config.yaml 失败,默认查询 1 天: {e}")
# 读取服务端日期偏移0=今天1=昨天…),单日:起止同日
offset = state_store.get_offset("中通")
print(f">> 正在设定查询时间范围为近【{query_days}】天...")
print(f">> 正在设定查询日期: 偏移 {offset}0=今天)...")
ewb_frame.locator("#beginDate").click()
page.wait_for_timeout(500)
@@ -161,15 +155,15 @@ def zto_expected_download_impl(page):
today_time_str = today_cell.get_attribute("time")
if today_time_str:
today_time = int(today_time_str)
start_time = today_time - (query_days - 1) * 86400000
start_cell = ewb_frame.locator(f"td div.day[time='{start_time}']").first
target_time = today_time - offset * 86400000
target_cell = ewb_frame.locator(f"td div.day[time='{target_time}']").first
if start_cell.is_visible():
start_cell.click()
if target_cell.is_visible():
target_cell.click()
page.wait_for_timeout(300)
today_cell.click()
target_cell.click()
else:
print(" ⚠️ 设定的天数过大,不在当前日历视窗内,自动降级为查询当天。")
print(" ⚠️ 偏移日期不在当前日历视窗内,自动降级为查询当天。")
today_cell.click()
page.wait_for_timeout(300)
today_cell.click()
@@ -369,17 +363,10 @@ def zto_actual_download_impl(page):
print(">> 正在检测主页面 (#daterange)...")
arr_frame.locator("#daterange").wait_for(state="attached", timeout=15000)
# 2. 读取 YAML 并设定时间范围
query_days = 1
try:
if os.path.exists(CONFIG_PATH):
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
config = yaml.safe_load(f) or {}
query_days = int(config.get("zto", {}).get("query_days", 1))
except Exception:
pass
# 2. 读取服务端日期偏移0=今天1=昨天…),单日:起止同日
offset = state_store.get_offset("中通")
print(f">> 正在设定查询时间范围为近【{query_days}】天...")
print(f">> 正在设定查询日期: 偏移 {offset}0=今天)...")
arr_frame.locator("#daterange").click()
page.wait_for_timeout(500)
@@ -389,15 +376,15 @@ def zto_actual_download_impl(page):
today_time_str = today_cell.get_attribute("time")
if today_time_str:
today_time = int(today_time_str)
start_time = today_time - (query_days - 1) * 86400000
start_cell = arr_frame.locator(f"td div.day[time='{start_time}']").first
target_time = today_time - offset * 86400000
target_cell = arr_frame.locator(f"td div.day[time='{target_time}']").first
# 日期格子用 _dom_click 直接派发事件Playwright 的 .click() 会先 hover 格子,
# 触发“范围长度”提示气泡(.date-range-length-tip)盖住格子,导致点击被判遮挡而超时。
if start_cell.is_visible():
_dom_click(start_cell)
if target_cell.is_visible():
_dom_click(target_cell)
page.wait_for_timeout(300)
_dom_click(today_cell)
_dom_click(target_cell)
else:
_dom_click(today_cell)
page.wait_for_timeout(300)