Integrate expected-vs-actual (应到未到) comparison into main_router

- 应到未到比对.py -> expected_undelivered.py(英文名);main() 的 sys.exit 改为
  return,使其可被 main_router 安全调用而不杀进程。
- main_router.py:菜单 [9] 改为调用 expected_undelivered.main()——全站点自动比对,
  输出 output/应到未到数据.xlsx(汇总报表 + 中通/顺心/韵达/安能 各站明细);移除被
  取代的旧 task_process_undelivered_data 及其专属 import pandas。
- .gitignore:忽略 output/(比对输出目录)。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-06-21 23:39:36 +08:00
parent dea9ad6e07
commit d55c460c2d
3 changed files with 537 additions and 64 deletions

View File

@@ -6,7 +6,6 @@ import subprocess
import time
import urllib.request
import yaml
import pandas as pd
from playwright.sync_api import sync_playwright
from paths import DOWNLOAD_DIR, CONFIG_PATH
@@ -18,6 +17,9 @@ import site_zto
import site_yunda
import site_anneng
# 应到未到比对(全站点,离线处理 downloads/ 下的应到/实到数据)
import expected_undelivered
# 定义网点及对应的初始登录 URL
SITES_CONFIG = {
"顺心": "https://sxne.sxjdfreight.com",
@@ -80,62 +82,11 @@ def launch_anneng(app_path):
return proc
def task_process_undelivered_data(site_name="顺心"):
"""应到未到比对:找出应到但未实到的运单 (按站点前缀)"""
print(f"\n▶ 开始执行【{site_name} - 应到未到数据处理】任务...")
download_dir = DOWNLOAD_DIR
expected_path = os.path.join(download_dir, f"{site_name}-应到货物数据.xlsx")
actual_path = os.path.join(download_dir, f"{site_name}-实到货物数据.xlsx")
output_path = os.path.join(download_dir, f"{site_name}-应到未到货物数据.xlsx")
if not os.path.exists(expected_path):
print(f"❌ 错误:找不到【{site_name}-应到货物数据】主文档:{expected_path}")
return
if not os.path.exists(actual_path):
print(f"❌ 错误:找不到【{site_name}-实到货物数据】主文档:{actual_path}")
return
try:
print(">> 正在载入本地 Excel 文档...")
# 全部按字符串读取并保留空串:避免 18 位运单号被当成浮点数丢精度,也避免空单元格变成 NaN。
df_expected = pd.read_excel(expected_path, dtype=str, keep_default_na=False)
df_actual = pd.read_excel(actual_path, dtype=str, keep_default_na=False)
if "运单号" not in df_expected.columns or "运单号" not in df_actual.columns:
print("❌ 校验失败:数据源缺少【运单号】字段,请检查导出配置。")
return
print(">> 正在比对应到与实到数据...")
# 统一运单号为去空白字符串,消除 int/float 与 str 混读导致 isin 永不命中的隐患
df_expected["运单号"] = df_expected["运单号"].astype(str).str.strip()
df_actual["运单号"] = df_actual["运单号"].astype(str).str.strip()
# 剔除空白运单号,避免空值被误判为“应到未到”
df_expected = df_expected[df_expected["运单号"] != ""]
actual_set = set(df_actual["运单号"]) - {""}
# Left Anti-Join在应到中找出不存在于实到里的运单号
df_undelivered = df_expected[~df_expected["运单号"].isin(actual_set)]
target_columns = ["班次号", "交接单号", "运单号"]
available_columns = [
col for col in target_columns if col in df_undelivered.columns
]
df_output = df_undelivered[available_columns]
print(f">> 比对完成,共筛选出【应到未到】运单: {len(df_output)} 条。")
df_output.to_excel(output_path, index=False)
print(f"====================================================")
print(f" 比对完成,结果已输出。")
print(f" 📁 输出路径: {output_path}")
print(f"====================================================")
except Exception as e:
print(f"❌ 比对过程中发生异常: {e}")
def run_undelivered_compare():
"""应到未到比对(全站点):调用 expected_undelivered读 downloads/ 下的应到/实到
数据,生成 output/应到未到数据.xlsx汇总报表 + 各站明细)。"""
print("\n▶ 开始执行【应到未到比对(全站点)】任务 ...")
expected_undelivered.main()
# ====================================================================
@@ -457,7 +408,9 @@ def run_multi_site_daemon():
print(" [8] 执行 - 全站点下载流程自动化测试 (交叉跑通校验)")
print("-" * 52)
print(" 全局离线数据处理")
print(" [9] 执行 - 异常数据清洗比对 (Left Anti-Join)")
print(
" [9] 执行 - 应到未到比对(全站点汇总,输出 output/应到未到数据.xlsx"
)
print("-" * 52)
print(" [0] 退出系统")
print("====================================================")
@@ -493,12 +446,7 @@ def run_multi_site_daemon():
elif choice == "8":
run_automation_test(pages_map)
elif choice == "9":
site_name = input(
"请输入要比对的网点名称 (如 顺心/中通/韵达): "
).strip()
if not site_name:
site_name = "顺心"
task_process_undelivered_data(site_name)
run_undelivered_compare()
elif choice == "0":
print("\n正在关闭浏览器并退出...")
break