Files
playwrite/docs/MAIN_CLEAN_EXECUTION.md
Misaka_Company 5024384c73 refactor: restructure main_clean.py with dependency injection and interfaces
Refactor discrete material cleaner to improve maintainability and testability:

- Introduce dependency injection pattern for service components
- Add interfaces (IPageNavigator, IMaterialExtractor, IDeletionChecker)
- Extract PageNavigator service for page navigation logic
- Extract MaterialExtractor service for data extraction
- Extract DatabaseDeletionChecker service for deletion logic
- Add MaterialInfo data model for structured data
- Centralize configuration (CleanerConfig, UIConstants)
- Implement separation of concerns across services layer

Also includes comprehensive execution mechanism documentation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 14:17:37 +08:00

22 KiB
Raw Blame History

main_clean.py 运行机制文档

1. 概述

1.1 系统简介

离散备料计划维护数据清理工具 是一个基于 Python + Playwright 开发的自动化工具,用于清理 YonBIP用友ERP 系统中的备料数据。该工具通过浏览器自动化技术访问 ERP 系统,提取生产订单的备料信息,并根据数据库查询结果判断哪些物料需要清理。

1.2 技术栈

  • Python 3.x: 主要开发语言
  • Playwright: 浏览器自动化框架Chromium
  • SQL Server: 数据库查询pyodbc
  • 数据类dataclass: 配置和数据模型

1.3 主要功能

  1. 自动登录 YonBIP ERP 系统
  2. 读取待处理的生产订单列表
  3. 遍历每个订单的备料计划
  4. 提取物料详细信息(编码、名称、数量等)
  5. 查询数据库判断物料是否需要删除
  6. 标记需要清理的物料(预留删除接口)

2. 系统架构图

graph TB
    subgraph "外部系统"
        ERP[YonBIP ERP 系统]
        DB[(SQL Server 数据库)]
        FILE[ProductionID.txt]
    end

    subgraph "配置层 (config/)"
        CONFIG[CleanerConfig<br/>清理器配置]
        UICONST[UIConstants<br/>UI 常量配置]
        UICONST -.-> SELECTORS[Selectors<br/>选择器]
        UICONST -.-> TIMEOUTS[Timeouts<br/>超时配置]
        UICONST -.-> RETRY[RetryConfig<br/>重试配置]
    end

    subgraph "服务层 (services/)"
        NAVIGATOR[PageNavigator<br/>页面导航服务]
        EXTRACTOR[MaterialExtractor<br/>物料提取服务]
        CHECKER[DatabaseDeletionChecker<br/>删除判断服务]
    end

    subgraph "业务逻辑层 (utils/)"
        CLEANER[DiscreteMaterialCleaner<br/>离散备料清理器]
    end

    subgraph "数据层 (models/)"
        MATERIAL[MaterialInfo<br/>物料信息模型]
    end

    subgraph "接口层 (interfaces/)"
        I1[IPageNavigator]
        I2[IMaterialExtractor]
        I3[IDeletionChecker]
    end

    FILE --> CLEANER
    CLEANER --> NAVIGATOR
    CLEANER --> EXTRACTOR
    CLEANER --> CHECKER
    CLEANER --> CONFIG
    CLEANER --> UICONST

    NAVIGATOR -.实现.-> I1
    EXTRACTOR -.实现.-> I2
    CHECKER -.实现.-> I3

    NAVIGATOR --> ERP
    EXTRACTOR --> ERP
    EXTRACTOR --> MATERIAL
    CHECKER --> DB
    CHECKER --> MATERIAL

    style ERP fill:#ff9999
    style DB fill:#99ccff
    style FILE fill:#99ff99
    style CLEANER fill:#ffcc99

3. 主执行流程图

flowchart TD
    START([开始: main函数]) --> INIT_CONFIG[创建 CleanerConfig<br/>配置用户名、密码、负责人等]
    INIT_CONFIG --> INIT_UI[创建 UIConstants<br/>选择器、超时、重试配置]
    INIT_UI --> DEP_INJ[依赖注入<br/>创建服务实例]

    DEP_INJ --> CREATE_NAV[创建 PageNavigator<br/>页面导航服务]
    DEP_INJ --> CREATE_EXT[创建 MaterialExtractor<br/>物料提取服务]
    DEP_INJ --> CREATE_CHK[创建 DatabaseDeletionChecker<br/>删除判断服务]

    CREATE_NAV --> CREATE_CLEANER[创建 DiscreteMaterialCleaner<br/>注入所有服务]
    CREATE_CHK --> CREATE_CLEANER
    CREATE_EXT --> CREATE_CLEANER

    CREATE_CLEANER --> READ_FILE[读取 ProductionID.txt<br/>获取生产总排号列表]
    READ_FILE --> CALL_CLEAN[调用 cleaner.clean方法]

    CALL_CLEAN --> PW_START[启动 Playwright]
    PW_START --> LOGIN[登录 ERP 系统<br/>获取 browser, context, page]

    LOGIN --> NAV_MAIN[导航到主页面<br/>获取 nested iframe]
    NAV_MAIN --> SETUP_QUERY[设置查询界面<br/>打开订单号查询]

    SETUP_QUERY --> READ_IDS[读取总排号]
    READ_IDS --> QUERY_DB[查询数据库<br/>获取生产订单号列表]

    QUERY_DB --> ORDER_LOOP{遍历订单列表}

    ORDER_LOOP --> QUERY_ORDER[查询订单<br/>填充订单号并点击查询]
    QUERY_ORDER --> WAIT_LOAD[等待页面加载完成]

    WAIT_LOAD --> DEBUG_CHECK{调试模式?}
    DEBUG_CHECK -->|是| PAUSE[暂停执行<br/>等待调试]
    DEBUG_CHECK -->|否| NAV_PLAN
    PAUSE --> NAV_PLAN[导航到备料计划页面]

    NAV_PLAN --> EXTRACT_COUNT[提取详细信息数量]
    EXTRACT_COUNT --> EXTRACT_STATUS[提取备料状态]

    EXTRACT_STATUS --> SHOULD_PROC{需要处理?}
    SHOULD_PROC -->|数量=0| SKIP[跳过订单]
    SHOULD_PROC -->|状态≠审批通过| SKIP
    SHOULD_PROC -->|是| ENTER_EDIT[进入编辑模式<br/>点击修改按钮]

    ENTER_EDIT --> EXPAND[展开物料列表<br/>点击展开按钮]
    EXPAND --> EXT_MATERIALS[提取所有物料信息<br/>遍历物料列表]

    EXT_MATERIALS --> MAT_LOOP{遍历物料}
    MAT_LOOP --> CHECK_DELETE[查询数据库<br/>判断是否需要删除]
    CHECK_DELETE --> MARK[标记物料<br/>设置 should_delete]
    MARK --> MAT_LOOP

    MAT_LOOP -->|完成| CLOSE_PAGE[关闭当前页面]
    CLOSE_PAGE --> SLEEP[等待 1 秒]
    SKIP --> ORDER_LOOP
    SLEEP --> ORDER_LOOP

    ORDER_LOOP -->|完成| LOGOUT[注销登录]
    LOGOUT --> CLOSE_ALL[关闭浏览器上下文]
    CLOSE_ALL --> END([结束])

    style START fill:#90EE90
    style END fill:#FFB6C1
    style ORDER_LOOP fill:#FFE4B5
    style MAT_LOOP fill:#FFE4B5
    style SHOULD_PROC fill:#FFD700

4. 组件交互时序图

sequenceDiagram
    participant Main as main()
    participant Cleaner as DiscreteMaterialCleaner
    participant Nav as PageNavigator
    participant Ext as MaterialExtractor
    participant Checker as DatabaseDeletionChecker
    participant ERP as YonBIP ERP
    participant DB as SQL Server

    Main->>Cleaner: clean(production_id_file)
    activate Cleaner

    Cleaner->>Cleaner: _initialize_browser()
    Note over Cleaner: 启动 Playwright 并登录

    Cleaner->>Nav: navigate_to_main_page(page)
    activate Nav
    Nav->>ERP: 点击功能菜单
    Nav->>ERP: 打开"离散生产订单维护"
    Nav-->>Cleaner: (page1, main_frame, inner_frame)
    deactivate Nav

    Cleaner->>Nav: setup_query_interface(inner_frame)
    activate Nav
    Nav->>ERP: 打开订单号查询界面
    Nav->>ERP: 设置显示数量为 5000
    deactivate Nav

    Cleaner->>Cleaner: _get_order_ids(production_id_file)
    Note over Cleaner: 读取文件并查询数据库

    loop 遍历每个订单
        Cleaner->>Cleaner: _query_order(inner_frame, order_id)
        Note over Cleaner: 填充订单号并点击查询
        Cleaner->>Nav: wait_for_page_loaded(inner_frame)
        activate Nav
        Nav->>ERP: 等待"加载中"消失
        deactivate Nav

        alt 调试模式
            Cleaner->>ERP: pause() 调试暂停
        end

        Cleaner->>Nav: navigate_to_material_plan_page(page1)
        activate Nav
        Nav->>ERP: 点击"更多" → "备料计划"
        Nav->>ERP: 等待页面加载完成
        Nav-->>Cleaner: (page2, plan_frame)
        deactivate Nav

        Cleaner->>Ext: extract_detail_count(plan_frame)
        activate Ext
        Ext->>ERP: 提取详细信息数量
        Ext-->>Cleaner: detail_count
        deactivate Ext

        Cleaner->>Ext: extract_detail_status(plan_frame)
        activate Ext
        Ext->>ERP: 提取备料状态
        Ext-->>Cleaner: detail_status
        deactivate Ext

        alt 需要处理订单
            Cleaner->>Cleaner: _enter_edit_mode(plan_frame)
            Note over Cleaner: 点击修改、展开按钮

            Cleaner->>Ext: extract_materials(plan_frame, count)
            activate Ext
            loop 遍历物料
                Ext->>ERP: 提取物料编码
                Ext->>ERP: 提取物料名称
                Ext->>ERP: 提取待发数量
                Ext->>ERP: 提取出库数量
            end
            Ext-->>Cleaner: materials (List[MaterialInfo])
            deactivate Ext

            loop 遍历每个物料
                Cleaner->>Checker: should_delete(material)
                activate Checker
                Checker->>DB: 查询物料负责人
                DB-->>Checker: 查询结果
                Checker-->>Cleaner: True/False
                deactivate Checker
                Cleaner->>Cleaner: material.should_delete = result
            end

            Cleaner->>ERP: 关闭页面
        else 不需要处理
            Cleaner->>ERP: 关闭页面
        end
    end

    Cleaner->>Cleaner: _cleanup()
    Cleaner->>ERP: 注销登录
    Cleaner->>Cleaner: 关闭浏览器

    Cleaner-->>Main: 完成
    deactivate Cleaner

5. 组件详细说明

5.1 DiscreteMaterialCleaner (utils/discrete_material_cleaner.py)

职责: 核心业务逻辑编排器,协调整个清理流程

主要方法:

  • clean(production_id_file) - 执行完整清理流程
  • _initialize_browser(playwright) - 初始化浏览器并登录
  • _get_order_ids(production_id_file) - 获取待处理订单列表
  • _process_order(inner_frame, order_id, order_index, page1) - 处理单个订单
  • _query_order(inner_frame, order_id, order_index) - 查询订单
  • _should_process_order(detail_count, detail_status, order_index) - 判断是否需要处理
  • _enter_edit_mode(frame) - 进入编辑模式
  • _cleanup(main_frame, context, browser) - 清理资源

依赖注入:

  • navigator: IPageNavigator - 页面导航
  • extractor: IMaterialExtractor - 物料提取
  • deletion_checker: IDeletionChecker - 删除判断

5.2 PageNavigator (services/page_navigator.py)

职责: 处理所有页面导航和 iframe 操作

主要方法:

  • navigate_to_main_page(page) - 导航到主页面
  • navigate_to_order_page(main_frame, page) - 导航到订单页面
  • navigate_to_material_plan_page(page) - 导航到备料计划页面
  • setup_query_interface(frame) - 设置查询界面
  • wait_for_page_loaded(frame) - 等待页面加载完成

关键特性:

  • 处理嵌套 iframe 结构 (#forwardFrame → #mainiframe)
  • 等待加载状态("加载中"提示)
  • 使用 expect_popup() 处理新窗口

5.3 MaterialExtractor (services/material_extractor.py)

职责: 从页面提取物料信息

主要方法:

  • extract_detail_count(frame) - 提取详细信息数量
  • extract_detail_status(frame) - 提取备料状态
  • extract_materials(frame, count) - 提取所有物料信息
  • _extract_material_code(child_form) - 提取物料编码
  • _extract_material_name(child_form) - 提取物料名称
  • _extract_pending_quantity(child_form) - 提取待发数量
  • _extract_shipped_quantity(child_form) - 提取出库数量
  • _navigate_to_next_material(child_form, current_index, total_count) - 导航到下一个物料

数据返回: List[MaterialInfo]


5.4 DatabaseDeletionChecker (services/deletion_checker.py)

职责: 基于数据库查询判断物料是否需要删除

主要方法:

  • should_delete(material: MaterialInfo) -> bool - 判断是否需要删除

逻辑:

  • 查询数据库中物料对应的负责人
  • 与配置的 manager_name 进行比对
  • 返回是否需要删除的布尔值

5.5 CleanerConfig (config/cleaner_config.py)

职责: 管理清理器运行配置

属性:

  • username: str - ERP 登录用户名
  • password: str - ERP 登录密码
  • manager_name: str - 负责人姓名(用于删除判断)
  • headless: bool - 是否无头模式运行浏览器
  • verbose: bool - 是否打印详细日志
  • debug_mode: bool - 是否启用调试模式
  • debug_order: Optional[int] - 调试的订单索引

5.6 UIConstants (config/ui_constants.py)

职责: 集中管理所有 UI 相关常量

包含三个嵌套数据类:

  1. Selectors - CSS 选择器

    • 搜索相关: SEARCH_BTN, SEARCH_ICON, QUERY_BY_ORDER
    • iframe: FORWARD_FRAME, MAIN_IFRAME
    • 按钮: MODIFY_BUTTON, SAVE_BUTTON, EXPAND_BUTTON
  2. Timeouts - 超时配置(毫秒)

    • 页面加载: IFRAME_VISIBLE, PLAN_CODE_VISIBLE
    • 加载等待: LOADING_VISIBLE_WAIT, LOADING_HIDDEN_WAIT
    • 轮询: PLAN_CODE_MAX_WAIT, PLAN_CHECK_INTERVAL
  3. RetryConfig - 重试配置

    • DISPLAY_COUNT_MAX_RETRIES - 最大重试次数
    • EXPECTED_DISPLAY_COUNT - 期望显示数量

5.7 MaterialInfo (models/material_info.py)

职责: 物料信息数据模型

属性:

  • serial_number: int - 序号
  • code: str - 物料编码
  • name: str - 物料名称
  • pending_quantity: str - 累计待发数量
  • shipped_quantity: str - 累计出库数量
  • should_delete: bool - 是否需要删除(默认 False

6. 配置类结构图

classDiagram
    class CleanerConfig {
        +str username
        +str password
        +str manager_name
        +bool headless
        +bool verbose
        +bool debug_mode
        +Optional~int~ debug_order
    }

    class UIConstants {
        +Selectors selectors
        +Timeouts timeouts
        +RetryConfig retry
    }

    class Selectors {
        +str SEARCH_BTN
        +str SEARCH_ICON
        +str QUERY_BY_ORDER
        +str TAB_ALL
        +str HOT_KEY_HEAD
        +str MORE_BUTTON
        +str MATERIAL_PLAN
        +str FORWARD_FRAME
        +str MAIN_IFRAME
        +str MODIFY_BUTTON
        +str SAVE_BUTTON
        +str EXPAND_BUTTON
        +str CARD_TABLE_SIDE_BOX
    }

    class Timeouts {
        +int IFRAME_VISIBLE
        +int PLAN_CODE_VISIBLE
        +int BUTTON_VISIBLE
        +int SERIAL_VISIBLE
        +int FORM_VISIBLE
        +int LOADING_VISIBLE_WAIT
        +int LOADING_HIDDEN_WAIT
        +int PLAN_CODE_MAX_WAIT
        +float PLAN_CHECK_INTERVAL
    }

    class RetryConfig {
        +int DISPLAY_COUNT_MAX_RETRIES
        +str EXPECTED_DISPLAY_COUNT
    }

    class MaterialInfo {
        +int serial_number
        +str code
        +str name
        +str pending_quantity
        +str shipped_quantity
        +bool should_delete
    }

    UIConstants *-- Selectors
    UIConstants *-- Timeouts
    UIConstants *-- RetryConfig

    CleanerConfig ..> UIConstants : 使用
    DiscreteMaterialCleaner ..> CleanerConfig : 依赖
    MaterialExtractor ..> MaterialInfo : 返回
    DatabaseDeletionChecker ..> MaterialInfo : 处理

7. 数据流图

flowchart LR
    subgraph "数据输入"
        FILE[ProductionID.txt<br/>生产总排号列表]
        CONFIG[CleanerConfig<br/>配置参数]
    end

    subgraph "数据处理"
        READ[read_production_ids<br/>读取总排号]
        QUERY[query_production_order_numbers<br/>查询数据库]
        EXTRACT[extract_materials<br/>提取物料信息]
        CHECK[should_delete<br/>删除判断]
    end

    subgraph "数据模型"
        IDs[总排号列表]
        OrderIDs[生产订单号列表]
        Materials[物料信息列表]
        Material[单个物料信息]
    end

    subgraph "外部系统"
        DB[(SQL Server)]
        ERP[YonBIP ERP]
    end

    FILE --> READ
    READ --> IDs
    IDs --> QUERY
    QUERY --> DB
    DB --> OrderIDs
    OrderIDs --> ERP
    ERP --> EXTRACT
    EXTRACT --> Materials
    Materials --> Material
    Material --> CHECK
    CHECK --> DB

    style FILE fill:#99ff99
    style DB fill:#99ccff
    style ERP fill:#ff9999
    style Materials fill:#ffcc99

8. 单个订单处理流程

flowchart TD
    START([开始处理订单]) --> QUERY[填充订单号]
    QUERY --> CLICK_SEARCH[点击查询按钮]
    CLICK_SEARCH --> WAIT_LOADING[等待加载完成]

    WAIT_LOADING --> NAV_PLAN[导航到备料计划页面]
    NAV_PLAN --> WAIT_PLAN[等待备料计划页面加载]

    WAIT_PLAN --> EXT_COUNT[提取详细信息数量]
    EXT_COUNT --> EXT_STATUS[提取备料状态]

    EXT_STATUS --> CHECK_COUNT{数量 > 0?}
    CHECK_COUNT -->|否| SKIP_CLOSE[关闭页面]
    CHECK_COUNT -->|是| CHECK_STATUS{状态 = 审批通过?}

    CHECK_STATUS -->|否| SKIP_CLOSE
    CHECK_STATUS -->|是| CLICK_MODIFY[点击修改按钮]

    CLICK_MODIFY --> WAIT_SAVE[等待保存按钮可见]
    WAIT_SAVE --> CLICK_EXPAND[点击展开按钮]
    CLICK_EXPAND --> EXT_LOOP{遍历物料}

    EXT_LOOP --> FIND_SERIAL[查找序号元素]
    FIND_SERIAL --> EXT_CODE[提取物料编码]
    EXT_CODE --> EXT_NAME[提取物料名称]
    EXT_NAME --> EXT_PENDING[提取待发数量]
    EXT_PENDING --> EXT_SHIPPED[提取出库数量]

    EXT_SHIPPED --> CREATE_OBJ[创建 MaterialInfo 对象]
    CREATE_OBJ --> CHECK_DELETE[查询数据库判断删除]

    CHECK_DELETE --> MARK_DELETE[标记 should_delete]
    MARK_DELETE --> NEXT_MAT{还有下一个?}
    NEXT_MAT -->|是| CLICK_NEXT[点击下一个按钮]
    CLICK_NEXT --> EXT_LOOP
    NEXT_MAT -->|否| CLICK_LAST[点击最后一个按钮]

    CLICK_LAST --> ADD_LIST[添加到物料列表]
    ADD_LIST --> CLOSE_PAGE[关闭页面]
    SKIP_CLOSE --> END([结束])
    CLOSE_PAGE --> END

    style START fill:#90EE90
    style END fill:#FFB6C1
    style EXT_LOOP fill:#FFE4B5
    style CHECK_COUNT fill:#FFD700
    style CHECK_STATUS fill:#FFD700

9. 关键设计模式

9.1 依赖注入模式

DiscreteMaterialCleaner 通过构造函数注入所有依赖服务,而不是直接创建实例:

cleaner = DiscreteMaterialCleaner(
    config=config,
    navigator=navigator,
    extractor=extractor,
    deletion_checker=deletion_checker,
)

优点:

  • 降低耦合度
  • 方便单元测试(可注入 Mock 对象)
  • 灵活替换实现

9.2 接口隔离原则

通过抽象接口定义服务契约:

  • IPageNavigator - 页面导航接口
  • IMaterialExtractor - 物料提取接口
  • IDeletionChecker - 删除判断接口

优点:

  • 职责分离清晰
  • 实现可替换
  • 便于扩展新功能

9.3 策略模式

IDeletionChecker 接口允许多种删除判断策略:

  • DatabaseDeletionChecker - 基于数据库查询
  • 可扩展其他策略(如基于规则、基于 API 等)

10. 嵌套 iframe 处理机制

YonBIP ERP 系统使用嵌套 iframe 结构,需要特殊处理:

page (浏览器上下文)
  └── #forwardFrame (外层 iframe)
      └── #mainiframe (内层 iframe包含实际应用 UI)

处理模式:

outer_frame = page.locator("#forwardFrame").content_frame
inner_frame_locator = outer_frame.locator("#mainiframe")
inner_frame_locator.wait_for(state="visible", timeout=15000)
inner_frame = inner_frame_locator.content_frame

关键点:

  • 必须等待内层 iframe 可见后再获取其 content_frame
  • 操作前确保元素已加载完成
  • 注意不同页面的 iframe 可能需要重新获取

11. 加载状态处理

ERP 系统使用"加载中"提示表示页面正在加载数据:

loading_locator = frame.locator("div").filter(has_text="加载中").nth(1)
try:
    loading_locator.wait_for(state="visible", timeout=3000)
    loading_locator.wait_for(state="hidden", timeout=0)  # 无限等待
except PlaywrightTimeoutError:
    # 加载很快完成或未出现
    pass

处理逻辑:

  1. 先尝试等待"加载中"出现
  2. 然后无限等待直到消失
  3. 如果超时则认为加载已完成

12. 运行示例

# 激活虚拟环境
.venv\Scripts\activate

# 运行清理脚本
python main_clean.py

输出示例:

================================================================================
开始执行离散备料计划维护数据清理
================================================================================
使用负责人 [彭羽] 进行数据清理
从文件读取到 10 个总排号
查询到 10 个生产订单号

=== 开始处理第 1 个订单,订单号: PO20250101001 ===
第 1 个订单查询完成,等待加载结果...
第 1 个订单加载完成,开始清理数据...
等待备料计划页面加载完成...
备料计划页面加载完成,编码: BL20250101001
详细信息数量: 5
备料状态: 审批通过
处理 序号 1
材料编码: 00000001001
材料名称: 原材料A
累计待发数量: 100
累计出库数量: 0
>>> 需要清理原材料A【00000001001】
...

开始执行账号注销...
=== 全部完成 ===

13. 扩展与维护

13.1 添加新的删除判断策略

实现 IDeletionChecker 接口:

class RuleBasedDeletionChecker(IDeletionChecker):
    def should_delete(self, material: MaterialInfo) -> bool:
        # 基于规则的判断逻辑
        return material.name.startswith("测试")

13.2 修改配置参数

编辑 main_clean.py 中的 CleanerConfig 初始化:

config = CleanerConfig(
    username="your_username",
    password="your_password",
    manager_name="新的负责人",
    headless=True,  # 无头模式
    verbose=False,  # 关闭详细日志
)

13.3 调试特定订单

启用调试模式:

config = CleanerConfig(
    debug_mode=True,
    debug_order=0,  # 调试第一个订单
)

14. 常见问题

Q1: 页面加载超时

A: 检查网络连接,调整 UIConstants.Timeouts 中的超时配置

Q2: iframe 未找到

A: 确认 ERP 系统版本未变化,检查 Selectors.FORWARD_FRAMESelectors.MAIN_IFRAME

Q3: 数据库查询失败

A: 检查 db/materials_to_delete.py 中的 SQL 连接配置

Q4: 物料信息提取错误

A: 使用 debug_mode=True 暂停执行,检查页面元素选择器


附录 A: 文件路径速查

文件 路径
主入口 main_clean.py
核心业务逻辑 utils/discrete_material_cleaner.py
页面导航服务 services/page_navigator.py
物料提取服务 services/material_extractor.py
删除判断服务 services/deletion_checker.py
清理器配置 config/cleaner_config.py
UI 常量配置 config/ui_constants.py
物料信息模型 models/material_info.py
页面导航接口 interfaces/i_page_navigator.py
物料提取接口 interfaces/i_material_extractor.py
删除判断接口 interfaces/i_deletion_checker.py

附录 B: 接口定义摘要

IPageNavigator

def navigate_to_main_page(page: Page) -> Frame
def navigate_to_order_page(main_frame: Frame, page: Page) -> Tuple[Page, Frame]
def navigate_to_material_plan_page(page: Page) -> Tuple[Page, Frame]
def setup_query_interface(frame: Frame) -> None
def wait_for_page_loaded(frame: Frame) -> bool

IMaterialExtractor

def extract_detail_count(frame: Frame) -> int
def extract_detail_status(frame: Frame) -> str
def extract_materials(frame: Frame, count: int) -> List[MaterialInfo]

IDeletionChecker

def should_delete(material: MaterialInfo) -> bool

文档版本: 1.0 最后更新: 2026-02-10 维护者: Claude Code